Commit 07127a0a by DJ Delorie Committed by DJ Delorie

addsub.md (addqi3): Disparage a0/a1.

* config/m32c/addsub.md (addqi3): Disparage a0/a1.
(addpsi3): Expand to include memory operands.  Remove
reload-specific splits.
* config/m32c/bitops.md (bset_qi, bset_hi, bclr_qi): New.
(andqi3_16, andhi3_16, iorqi3_16, iorhi3_16): New.
(andqi3_24, andhi3_24, iorqi3_24, iorhi3_24): New.
(andqi3, andhi3, iorqi3, iorhi3): Convert to expanders.
(shift1_qi, shift1_hi, insv): New.
* config/m32c/cond.md (cbranchqi4, cbranchhi4): Remove.
(cbranch<mode>4, stzx_16, stzx_24_<mode>, stzx_reversed,
cmp<mode>, b<code>, s<code>, s<code>_24, movqicc, movhicc,
cond_to_int): New.
* config/m32c/m32c-protos.h: Update as needed.
* config/m32c/m32c.c (m32c_reg_class_from_constraint): Don't
default the Rcr, Rcl, Raw, and Ral constraints.  Add Ra0 and Ra1.
Fail for unrecognized R* constraints.
(m32c_cannot_change_mode_class): Be more picky about pseudos.
(m32c_const_ok_for_constraint_p): Add Imb, Imw, and I00.
(m32c_extra_constraint_p2): Allow (mem (plus (plus fb int) int)).
Add Sp constraint.
(m32c_init_libfuncs): New.
(m32c_legitimate_address_p): Add debug wrapper.
(m32c_rtx_costs): New.
(m32c_address_cost): New.
(conversions): Add 'B' prefix.
(m32c_print_operand): 'h' and 'H' pick lower and upper halves of
operands, or word regnames for QI operands.  'B' prints bit
position.
(m32c_expand_setmemhi): New.
(m32c_expand_movmemhi): New.
(m32c_expand_movstr): New.
(m32c_expand_cmpstr): New.
(m32c_prepare_shift): Shift counts are limited to 16 bits at a time.
(m32c_expand_neg_mulpsi3): Handle non-ints.
(m32c_cmp_flg_0): New.
(m32c_expand_movcc): New.
(m32c_expand_insv): New.
(m32c_scc_pattern): New.
* config/m32c/m32c.h (reg classes): Add AO_REGS and A1_REGS.  Take
a0/a1 out of SIregs.
(STORE_FLAG_VALUE): New.
* config/m32c/m32c.md: Add unspecs for string moves.  Define various mode and
code macros.
(no_insn): New.
* config/m32c/mov.md: Make constraints more liberal.
(zero_extendqihi2): Optimize r0/r1 case.
* config/m32c/muldiv.md (mulpsi3): Check for intvals.
* config/m32c/predicates.md (m32c_any_operand): New.
(m32c_nonimmediate_operand): New.
(m32c_hl_operand): New.
(m32c_r3_operand): New.
(ap_operand): New.
(ma_operand): New.
(memsym_operand): New.
(memimmed_operand): New.
(a_qi_operand): New.
(m32c_eqne_operator): New.
(m32c_1bit8_operand): New.
(m32c_1bit16_operand): New.
(m32c_1mask8_operand): New.
(m32c_1mask16_operand): New.
* config/m32c/blkmov.md: New file.
* config/m32c/t-m32c (MD_FILES): Add blkmov.

From-SVN: r111859
parent 8b3a0b71
2006-03-08 DJ Delorie <dj@redhat.com>
* config/m32c/addsub.md (addqi3): Disparage a0/a1.
(addpsi3): Expand to include memory operands. Remove
reload-specific splits.
* config/m32c/bitops.md (bset_qi, bset_hi, bclr_qi): New.
(andqi3_16, andhi3_16, iorqi3_16, iorhi3_16): New.
(andqi3_24, andhi3_24, iorqi3_24, iorhi3_24): New.
(andqi3, andhi3, iorqi3, iorhi3): Convert to expanders.
(shift1_qi, shift1_hi, insv): New.
* config/m32c/cond.md (cbranchqi4, cbranchhi4): Remove.
(cbranch<mode>4, stzx_16, stzx_24_<mode>, stzx_reversed,
cmp<mode>, b<code>, s<code>, s<code>_24, movqicc, movhicc,
cond_to_int): New.
* config/m32c/m32c-protos.h: Update as needed.
* config/m32c/m32c.c (m32c_reg_class_from_constraint): Don't
default the Rcr, Rcl, Raw, and Ral constraints. Add Ra0 and Ra1.
Fail for unrecognized R* constraints.
(m32c_cannot_change_mode_class): Be more picky about pseudos.
(m32c_const_ok_for_constraint_p): Add Imb, Imw, and I00.
(m32c_extra_constraint_p2): Allow (mem (plus (plus fb int) int)).
Add Sp constraint.
(m32c_init_libfuncs): New.
(m32c_legitimate_address_p): Add debug wrapper.
(m32c_rtx_costs): New.
(m32c_address_cost): New.
(conversions): Add 'B' prefix.
(m32c_print_operand): 'h' and 'H' pick lower and upper halves of
operands, or word regnames for QI operands. 'B' prints bit
position.
(m32c_expand_setmemhi): New.
(m32c_expand_movmemhi): New.
(m32c_expand_movstr): New.
(m32c_expand_cmpstr): New.
(m32c_prepare_shift): Shift counts are limited to 16 bits at a time.
(m32c_expand_neg_mulpsi3): Handle non-ints.
(m32c_cmp_flg_0): New.
(m32c_expand_movcc): New.
(m32c_expand_insv): New.
(m32c_scc_pattern): New.
* config/m32c/m32c.h (reg classes): Add AO_REGS and A1_REGS. Take
a0/a1 out of SIregs.
(STORE_FLAG_VALUE): New.
* config/m32c/m32c.md: Add unspecs for string moves. Define various mode and
code macros.
(no_insn): New.
* config/m32c/mov.md: Make constraints more liberal.
(zero_extendqihi2): Optimize r0/r1 case.
* config/m32c/muldiv.md (mulpsi3): Check for intvals.
* config/m32c/predicates.md (m32c_any_operand): New.
(m32c_nonimmediate_operand): New.
(m32c_hl_operand): New.
(m32c_r3_operand): New.
(ap_operand): New.
(ma_operand): New.
(memsym_operand): New.
(memimmed_operand): New.
(a_qi_operand): New.
(m32c_eqne_operator): New.
(m32c_1bit8_operand): New.
(m32c_1bit16_operand): New.
(m32c_1mask8_operand): New.
(m32c_1mask16_operand): New.
* config/m32c/blkmov.md: New file.
* config/m32c/t-m32c (MD_FILES): Add blkmov.
2006-03-08 Andreas Tobler <a.tobler@schweiz.ch> 2006-03-08 Andreas Tobler <a.tobler@schweiz.ch>
* dwarf2out.c (expand_builtin_dwarf_sp_column): Make dwarf_regnum * dwarf2out.c (expand_builtin_dwarf_sp_column): Make dwarf_regnum
......
...@@ -24,22 +24,22 @@ ...@@ -24,22 +24,22 @@
(define_insn "addqi3" (define_insn "addqi3"
[(set (match_operand:QI 0 "mra_or_sp_operand" [(set (match_operand:QI 0 "mra_or_sp_operand"
"=SdRhl,SdRhl,??Rmm,??Rmm, Raa,Raa,SdRhl,??Rmm") "=SdRhl,SdRhl,??Rmm,??Rmm, *Raa,*Raa,SdRhl,??Rmm")
(plus:QI (match_operand:QI 1 "mra_operand" (plus:QI (match_operand:QI 1 "mra_operand"
"%0,0,0,0, 0,0,0,0") "%0,0,0,0, 0,0,0,0")
(match_operand:QI 2 "mrai_operand" (match_operand:QI 2 "mrai_operand"
"iSdRhl,?Rmm,iSdRhl,?Rmm, iSdRhl,?Rmm,Raa,Raa")))] "iSdRhl,?Rmm,iSdRhl,?Rmm, iSdRhl,?Rmm,*Raa,*Raa")))]
"" ""
"add.b\t%2,%0" "add.b\t%2,%0"
[(set_attr "flags" "oszc")] [(set_attr "flags" "oszc")]
) )
(define_insn "addhi3" (define_insn "addhi3"
[(set (match_operand:HI 0 "nonimmediate_operand" [(set (match_operand:HI 0 "m32c_nonimmediate_operand"
"=SdRhi,SdRhi,??Rmm,??Rmm, SdRhi,??Rmm, Rhi, Raw, Raw, !Rsp") "=SdRhi,SdRhi,??Rmm,??Rmm, SdRhi,??Rmm, Rhi, Raw, Raw, !Rsp")
(plus:HI (match_operand:HI 1 "general_operand" (plus:HI (match_operand:HI 1 "m32c_any_operand"
"%0,0,0,0, 0,0, Raw, Rfb, Rfb, 0") "%0,0,0,0, 0,0, Raw, Rfb, Rfb, 0")
(match_operand:HI 2 "general_operand" (match_operand:HI 2 "m32c_any_operand"
"IU2sSdRhi,?Rmm,IU2sSdRhi,?Rmm, IM2,IM2, IS2IU2, I00, IS1, i")))] "IU2sSdRhi,?Rmm,IU2sSdRhi,?Rmm, IM2,IM2, IS2IU2, I00, IS1, i")))]
"" ""
"@ "@
...@@ -57,45 +57,19 @@ ...@@ -57,45 +57,19 @@
) )
(define_insn "addpsi3" (define_insn "addpsi3"
[(set (match_operand:PSI 0 "nonimmediate_operand" "=SdRpi,SdRpi,Rsp*Rmm, Rpi,Rpi,Rhi,&Rhi") [(set (match_operand:PSI 0 "m32c_nonimmediate_operand" "=Rpi,Raa,SdRpi,SdRpi,Rsp*Rmm, Rpi,Rpi")
(plus:PSI (match_operand:PSI 1 "nonimmediate_operand" "0,0,0, Raa,Rad,!Rcl,Rhi") (plus:PSI (match_operand:PSI 1 "m32c_nonimmediate_operand" "0,0,0,0,0, Raa,Rad")
(match_operand:PSI 2 "general_operand" "iSdRpi,?Rmm,i, i,IS2,i,!Rcl")))] (match_operand:PSI 2 "m32c_any_operand" "Is3,IS1,iSdRpi,?Rmm,i, i,IS2")))]
"TARGET_A24" "TARGET_A24"
"@ "@
add.%&\t%2,%0 add.l:q\t%2,%0
add.%&\t%2,%0 addx\t%2,%0
add.%&\t%2,%0 add.l\t%2,%0
add.l\t%2,%0
add.l\t%2,%0
mova\t%d2[%1],%0 mova\t%d2[%1],%0
mova\t%D2[%1],%0 mova\t%D2[%1],%0"
# [(set_attr "flags" "oszc,oszc,oszc,oszc,oszc,*,*")]
#"
[(set_attr "flags" "oszc,oszc,oszc,*,*,oszc,oszc")]
)
; This is needed for reloading large frames.
(define_split
[(set (match_operand:PSI 0 "ra_operand" "")
(plus:PSI (match_operand:PSI 1 "cr_operand" "")
(match_operand:PSI 2 "immediate_operand" "")))]
""
[(set (match_dup 0) (match_dup 1))
(set (match_dup 0)
(plus:PSI (match_dup 0)
(match_dup 2)))]
""
)
; This is needed for reloading large frames.
(define_split
[(set (match_operand:PSI 0 "ra_operand" "")
(plus:PSI (match_operand:PSI 1 "ra_operand" "")
(match_operand:PSI 2 "cr_operand" "")))]
""
[(set (match_dup 0) (match_dup 2))
(set (match_dup 0)
(plus:PSI (match_dup 0)
(match_dup 1)))]
""
) )
(define_insn "subqi3" (define_insn "subqi3"
......
...@@ -22,40 +22,247 @@ ...@@ -22,40 +22,247 @@
;; Bit-wise operations (and, ior, xor, shift) ;; Bit-wise operations (and, ior, xor, shift)
(define_insn "andqi3" ; On the R8C and M16C, "address" for bit instructions is usually (but
[(set (match_operand:QI 0 "mra_operand" "=RhlSd,RhlSd,??Rmm,??Rmm") ; not always!) the *bit* address, not the *byte* address. This
(and:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0") ; confuses gcc, so we avoid cases where gcc would produce the wrong
(match_operand:QI 2 "mrai_operand" "iRhlSd,?Rmm,iRhlSd,?Rmm")))] ; code. We're left with absolute addresses and registers, and the odd
; case of shifting a bit by a variable.
; On the M32C, "address" for bit instructions is a regular address,
; and the bit number is stored in a separate field. Thus, we can let
; gcc do more interesting things. However, the M32C cannot set all
; the bits in a 16 bit register, which the R8C/M16C can do.
; However, it all means that we end up with two sets of patterns, one
; for each chip.
;;----------------------------------------------------------------------
;; First off, all the ways we can set one bit, other than plain IOR.
(define_insn "bset_qi"
[(set (match_operand:QI 0 "memsym_operand" "+Si")
(ior:QI (subreg:QI (ashift:HI (const_int 1)
(subreg:QI (match_operand:HI 1 "a_qi_operand" "Raa") 0)) 0)
(match_operand:QI 2 "" "0")))]
"TARGET_A16"
"bset\t%0[%1]"
[(set_attr "flags" "sz")]
)
(define_insn "bset_hi"
[(set (zero_extract:HI (match_operand:QI 0 "memsym_operand" "+Si")
(const_int 1)
(zero_extend:HI (subreg:QI (match_operand:HI 1 "a_qi_operand" "Raa") 0)))
(const_int 1))]
"TARGET_A16"
"bset\t%0[%1]"
[(set_attr "flags" "sz")]
)
;;----------------------------------------------------------------------
;; Now all the ways we can clear one bit, other than plain AND.
; This is odd because the shift patterns use QI counts, but we can't
; easily put QI in $aN without causing problems elsewhere.
(define_insn "bclr_qi"
[(set (zero_extract:HI (match_operand:QI 0 "memsym_operand" "+Si")
(const_int 1)
(zero_extend:HI (subreg:QI (match_operand:HI 1 "a_qi_operand" "Raa") 0)))
(const_int 0))]
"TARGET_A16"
"bclr\t%0[%1]"
[(set_attr "flags" "sz")]
)
;;----------------------------------------------------------------------
;; Now the generic patterns.
(define_insn "andqi3_16"
[(set (match_operand:QI 0 "mra_operand" "=Sp,Rqi,RhlSd,RhlSd,??Rmm,??Rmm")
(and:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0")
(match_operand 2 "mrai_operand" "Imb,Imb,iRhlSd,?Rmm,iRhlSd,?Rmm")))]
"TARGET_A16"
"@
bclr\t%B2,%0
bclr\t%B2,%h0
and.b\t%x2,%0
and.b\t%x2,%0
and.b\t%x2,%0
and.b\t%x2,%0"
[(set_attr "flags" "n,n,sz,sz,sz,sz")]
)
(define_insn "andhi3_16"
[(set (match_operand:HI 0 "mra_operand" "=Sp,Sp,Rhi,RhiSd,??Rmm,RhiSd,??Rmm")
(and:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0,0,0,0")
(match_operand:HI 2 "mrai_operand" "Imb,Imw,Imw,iRhiSd,?Rmm,?Rmm,iRhiSd")))]
"TARGET_A16"
"@
bclr\t%B2,%0
bclr\t%B2-8,1+%0
bclr\t%B2,%0
and.w\t%X2,%0
and.w\t%X2,%0
and.w\t%X2,%0
and.w\t%X2,%0"
[(set_attr "flags" "n,n,n,sz,sz,sz,sz")]
)
(define_insn "iorqi3_16"
[(set (match_operand:QI 0 "mra_operand" "=Sp,Rqi,RqiSd,??Rmm,RqiSd,??Rmm")
(ior:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0")
(match_operand:QI 2 "mrai_operand" "Ilb,Ilb,iRhlSd,iRhlSd,?Rmm,?Rmm")))]
"TARGET_A16"
"@
bset\t%B2,%0
bset\t%B2,%h0
or.b\t%x2,%0
or.b\t%x2,%0
or.b\t%x2,%0
or.b\t%x2,%0"
[(set_attr "flags" "n,n,sz,sz,sz,sz")]
)
(define_insn "iorhi3_16"
[(set (match_operand:HI 0 "mra_operand" "=Sp,Sp,Rhi,RhiSd,RhiSd,??Rmm,??Rmm")
(ior:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0,0,0,0")
(match_operand:HI 2 "mrai_operand" "Imb,Imw,Ilw,iRhiSd,?Rmm,iRhiSd,?Rmm")))]
"TARGET_A16"
"@
bset %B2,%0
bset\t%B2-8,1+%0
bset\t%B2,%0
or.w\t%X2,%0
or.w\t%X2,%0
or.w\t%X2,%0
or.w\t%X2,%0"
[(set_attr "flags" "n,n,n,sz,sz,sz,sz")]
)
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(define_insn "andqi3_24"
[(set (match_operand:QI 0 "mra_operand" "=Sd,Rqi,RhlSd,RhlSd,??Rmm,??Rmm")
(and:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0")
(match_operand 2 "mrai_operand" "Imb,Imb,iRhlSd,?Rmm,iRhlSd,?Rmm")))]
"TARGET_A24"
"@
bclr\t%B2,%0
bclr\t%B2,%0
and.b\t%x2,%0
and.b\t%x2,%0
and.b\t%x2,%0
and.b\t%x2,%0"
[(set_attr "flags" "n,n,sz,sz,sz,sz")]
)
(define_insn "andhi3_24"
[(set (match_operand:HI 0 "mra_operand" "=Sd,Sd,Rqi,Rqi,RhiSd,??Rmm,RhiSd,??Rmm")
(and:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0,0,0,0,0")
(match_operand:HI 2 "mrai_operand" "Imb,Imw,Imb,Imw,iRhiSd,?Rmm,?Rmm,iRhiSd")))]
"TARGET_A24"
"@
bclr\t%B2,%0
bclr\t%B2-8,1+%0
bclr\t%B2,%h0
bclr\t%B2-8,%H0
and.w\t%X2,%0
and.w\t%X2,%0
and.w\t%X2,%0
and.w\t%X2,%0"
[(set_attr "flags" "n,n,n,n,sz,sz,sz,sz")]
)
(define_insn "iorqi3_24"
[(set (match_operand:QI 0 "mra_operand" "=Sd,Rqi,RqiSd,??Rmm,RqiSd,??Rmm")
(ior:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0")
(match_operand:QI 2 "mrai_operand" "Ilb,Ilb,iRhlSd,iRhlSd,?Rmm,?Rmm")))]
"TARGET_A24"
"@
bset\t%B2,%0
bset\t%B2,%0
or.b\t%x2,%0
or.b\t%x2,%0
or.b\t%x2,%0
or.b\t%x2,%0"
[(set_attr "flags" "n,n,sz,sz,sz,sz")]
)
(define_insn "iorhi3_24"
[(set (match_operand:HI 0 "mra_operand" "=Sd,Sd,Rqi,Rqi,RhiSd,RhiSd,??Rmm,??Rmm")
(ior:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0,0,0,0,0")
(match_operand:HI 2 "mrai_operand" "Ilb,Ilw,Ilb,Ilw,iRhiSd,?Rmm,iRhiSd,?Rmm")))]
"TARGET_A24"
"@
bset\t%B2,%0
bset\t%B2-8,1+%0
bset\t%B2,%h0
bset\t%B2-8,%H0
or.w\t%X2,%0
or.w\t%X2,%0
or.w\t%X2,%0
or.w\t%X2,%0"
[(set_attr "flags" "n,n,n,n,sz,sz,sz,sz")]
)
; ----------------------------------------------------------------------
(define_expand "andqi3"
[(set (match_operand:QI 0 "mra_operand" "")
(and:QI (match_operand:QI 1 "mra_operand" "")
(match_operand:QI 2 "mrai_operand" "")))]
"" ""
"and.b\t%x2,%0" "if (TARGET_A16)
[(set_attr "flags" "sz,sz,sz,sz")] emit_insn (gen_andqi3_16 (operands[0], operands[1], operands[2]));
else
emit_insn (gen_andqi3_24 (operands[0], operands[1], operands[2]));
DONE;"
) )
(define_insn "andhi3" (define_expand "andhi3"
[(set (match_operand:HI 0 "mra_operand" "=RhiSd,??Rmm,RhiSd,??Rmm") [(set (match_operand:HI 0 "mra_operand" "")
(and:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0") (and:HI (match_operand:HI 1 "mra_operand" "")
(match_operand:HI 2 "mrai_operand" "iRhiSd,?Rmm,?Rmm,iRhiSd")))] (match_operand:HI 2 "mrai_operand" "")))]
"" ""
"and.w\t%X2,%0" "if (TARGET_A16)
[(set_attr "flags" "sz,sz,sz,sz")] emit_insn (gen_andhi3_16 (operands[0], operands[1], operands[2]));
else
emit_insn (gen_andhi3_24 (operands[0], operands[1], operands[2]));
DONE;"
) )
(define_insn "iorqi3" (define_expand "iorqi3"
[(set (match_operand:QI 0 "mra_operand" "=RqiSd,??Rmm,RqiSd,??Rmm") [(set (match_operand:QI 0 "mra_operand" "")
(ior:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0") (ior:QI (match_operand:QI 1 "mra_operand" "")
(match_operand:QI 2 "mrai_operand" "iRhlSd,iRhlSd,?Rmm,?Rmm")))] (match_operand:QI 2 "mrai_operand" "")))]
"" ""
"or.b\t%x2,%0" "if (TARGET_A16)
[(set_attr "flags" "sz,sz,sz,sz")] emit_insn (gen_iorqi3_16 (operands[0], operands[1], operands[2]));
else
emit_insn (gen_iorqi3_24 (operands[0], operands[1], operands[2]));
DONE;"
) )
(define_insn "iorhi3" (define_expand "iorhi3"
[(set (match_operand:HI 0 "mra_operand" "=RhiSd,RhiSd,??Rmm,??Rmm") [(set (match_operand:HI 0 "mra_operand" "")
(ior:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0") (ior:HI (match_operand:HI 1 "mra_operand" "")
(match_operand:HI 2 "mrai_operand" "iRhiSd,?Rmm,iRhiSd,?Rmm")))] (match_operand:HI 2 "mrai_operand" "")))]
"" ""
"or.w\t%X2,%0" "if (TARGET_A16)
[(set_attr "flags" "sz,sz,sz,sz")] emit_insn (gen_iorhi3_16 (operands[0], operands[1], operands[2]));
else
emit_insn (gen_iorhi3_24 (operands[0], operands[1], operands[2]));
DONE;"
) )
(define_insn "xorqi3" (define_insn "xorqi3"
...@@ -91,3 +298,38 @@ ...@@ -91,3 +298,38 @@
"not.w\t%0" "not.w\t%0"
[(set_attr "flags" "sz,sz")] [(set_attr "flags" "sz,sz")]
) )
; Optimizations using bit opcodes
; We need this because combine only looks at three insns at a time,
; and the bclr_qi pattern uses four - mov, shift, not, and. GCC
; should never expand this pattern, because it only shifts a constant
; by a constant, so gcc should do that itself.
(define_insn "shift1_qi"
[(set (match_operand:QI 0 "mra_operand" "=Rqi")
(ashift:QI (const_int 1)
(match_operand 1 "const_int_operand" "In4")))]
""
"mov.b\t#1,%0\n\tshl.b\t%1,%0"
)
(define_insn "shift1_hi"
[(set (match_operand:HI 0 "mra_operand" "=Rhi")
(ashift:HI (const_int 1)
(match_operand 1 "const_int_operand" "In4")))]
""
"mov.w\t#1,%0\n\tshl.w\t%1,%0"
)
; Generic insert-bit expander, needed so that we can use the bit
; opcodes for volatile bitfields.
(define_expand "insv"
[(set (zero_extract:HI (match_operand:HI 0 "mra_operand" "")
(match_operand 1 "const_int_operand" "")
(match_operand 2 "const_int_operand" ""))
(match_operand:HI 3 "const_int_operand" ""))]
""
"if (m32c_expand_insv (operands))
FAIL;
DONE;"
)
;; Machine Descriptions for R8C/M16C/M32C
;; Copyright (C) 2006
;; Free Software Foundation, Inc.
;; Contributed by Red Hat.
;;
;; This file is part of GCC.
;;
;; GCC is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published
;; by the Free Software Foundation; either version 2, or (at your
;; option) any later version.
;;
;; GCC is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
;; License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING. If not, write to the Free
;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
;; 02110-1301, USA.
;; various block move instructions
;; R8C:
;; SMOVB - while (r3--) { *a1-- = *r1ha0--; } - memcpy
;; SMOVF - while (r3--) { *a1++ = *r1ha0++; } - memcpy
;; SSTR - while (r3--) { *a1++ = [r0l,r0]; } - memset
;; M32CM:
;; SCMPU - while (*a0 && *a0 != *a1) { a0++; a1++; } - strcmp
;; SIN - while (r3--) { *a1++ = *a0; }
;; SMOVB - while (r3--) { *a1-- = *a0--; } - memcpy
;; SMOVF - while (r3--) { *a1++ = *a0++; } - memcpy
;; SMOVU - while (*a1++ = *a0++) ; - strcpy
;; SOUT - while (r3--) { *a1 = *a0++; }
;; SSTR - while (r3--) { *a1++ = [r0l,r0]; } - memset
;; 0 = destination (mem:BLK ...)
;; 1 = source (mem:BLK ...)
;; 2 = count
;; 3 = alignment
(define_expand "movmemhi"
[(match_operand 0 "ap_operand" "")
(match_operand 1 "ap_operand" "")
(match_operand 2 "m32c_r3_operand" "")
(match_operand 3 "" "")
]
""
"if (m32c_expand_movmemhi(operands)) DONE; FAIL;"
)
;; We can't use mode macros for these because M16C uses r1h to extend
;; the source address, for copying data from ROM to RAM. We don't yet
;; support that, but we need to zero our r1h, so the patterns differ.
;; 0 = dest (out)
;; 1 = src (out)
;; 2 = count (out)
;; 3 = dest (in)
;; 4 = src (in)
;; 5 = count (in)
(define_insn "movmemhi_bhi_op"
[(set (mem:QI (match_operand:HI 3 "ap_operand" "0"))
(mem:QI (match_operand:HI 4 "ap_operand" "1")))
(set (match_operand:HI 2 "m32c_r3_operand" "=R3w")
(const_int 0))
(set (match_operand:HI 0 "ap_operand" "=Ra1")
(plus:HI (match_dup 3)
(zero_extend:HI (match_operand:HI 5 "m32c_r3_operand" "2"))))
(set (match_operand:HI 1 "ap_operand" "=Ra0")
(plus:HI (match_dup 4)
(zero_extend:HI (match_dup 5))))
(use (reg:HI R1_REGNO))]
"TARGET_A16"
"mov.b:q\t#0,r1h\n\tsmovf.b\t; %0[0..%2-1]=r1h%1[]"
)
(define_insn "movmemhi_bpsi_op"
[(set (mem:QI (match_operand:PSI 3 "ap_operand" "0"))
(mem:QI (match_operand:PSI 4 "ap_operand" "1")))
(set (match_operand:HI 2 "m32c_r3_operand" "=R3w")
(const_int 0))
(set (match_operand:PSI 0 "ap_operand" "=Ra1")
(plus:PSI (match_dup 3)
(zero_extend:PSI (match_operand:HI 5 "m32c_r3_operand" "2"))))
(set (match_operand:PSI 1 "ap_operand" "=Ra0")
(plus:PSI (match_dup 4)
(zero_extend:PSI (match_dup 5))))]
"TARGET_A24"
"smovf.b\t; %0[0..%2-1]=%1[]"
)
(define_insn "movmemhi_whi_op"
[(set (mem:HI (match_operand:HI 3 "ap_operand" "0"))
(mem:HI (match_operand:HI 4 "ap_operand" "1")))
(set (match_operand:HI 2 "m32c_r3_operand" "=R3w")
(const_int 0))
(set (match_operand:HI 0 "ap_operand" "=Ra1")
(plus:HI (match_dup 3)
(zero_extend:HI (match_operand:HI 5 "m32c_r3_operand" "2"))))
(set (match_operand:HI 1 "ap_operand" "=Ra0")
(plus:HI (match_dup 4)
(zero_extend:HI (match_dup 5))))
(use (reg:HI R1_REGNO))]
"TARGET_A16"
"mov.b:q\t#0,r1h\n\tsmovf.w\t; %0[0..%2-1]=r1h%1[]"
)
(define_insn "movmemhi_wpsi_op"
[(set (mem:HI (match_operand:PSI 3 "ap_operand" "0"))
(mem:HI (match_operand:PSI 4 "ap_operand" "1")))
(set (match_operand:HI 2 "m32c_r3_operand" "=R3w")
(const_int 0))
(set (match_operand:PSI 0 "ap_operand" "=Ra1")
(plus:PSI (match_dup 3)
(zero_extend:PSI (match_operand:HI 5 "m32c_r3_operand" "2"))))
(set (match_operand:PSI 1 "ap_operand" "=Ra0")
(plus:PSI (match_dup 4)
(zero_extend:PSI (match_dup 5))))]
"TARGET_A24"
"smovf.w\t; %0[0..%2-1]=%1[]"
)
;; 0 = destination (mem:BLK ...)
;; 1 = number of bytes
;; 2 = value to store
;; 3 = alignment
(define_expand "setmemhi"
[(match_operand 0 "ap_operand" "")
(match_operand 1 "m32c_r3_operand" "")
(match_operand 2 "m32c_r0_operand" "")
(match_operand 3 "" "")
]
"TARGET_A24"
"if (m32c_expand_setmemhi(operands)) DONE; FAIL;"
)
;; 0 = address (out)
;; 1 = count (out)
;; 2 = value (in)
;; 3 = address (in)
;; 4 = count (in)
(define_insn "setmemhi_b<mode>_op"
[(set (mem:QI (match_operand:HPSI 3 "ap_operand" "0"))
(match_operand:QI 2 "m32c_r0_operand" "R0w"))
(set (match_operand:HI 1 "m32c_r3_operand" "=R3w")
(const_int 0))
(set (match_operand:HPSI 0 "ap_operand" "=Ra1")
(plus:HPSI (match_dup 3)
(zero_extend:HPSI (match_operand:HI 4 "m32c_r3_operand" "1"))))]
"TARGET_A24"
"sstr.b\t; %0[0..%1-1]=%2"
)
(define_insn "setmemhi_w<mode>_op"
[(set (mem:HI (match_operand:HPSI 3 "ap_operand" "0"))
(match_operand:HI 2 "m32c_r0_operand" "R0w"))
(set (match_operand:HI 1 "m32c_r3_operand" "=R3w")
(const_int 0))
(set (match_operand:HPSI 0 "ap_operand" "=Ra1")
(plus:HPSI (match_dup 3)
(zero_extend:HPSI (match_operand:HI 4 "m32c_r3_operand" "1"))))]
"TARGET_A24"
"sstr.w\t; %0[0..%1-1]=%2"
)
;; SCMPU sets the flags according to the result of the string
;; comparison. GCC wants the result to be a signed value reflecting
;; the result, which it then compares to zero. Hopefully we can
;; optimize that later (see peephole in cond.md). Meanwhile, the
;; strcmp builtin is expanded to a SCMPU followed by a flags-to-int
;; pattern in cond.md.
;; 0 = result:HI
;; 1 = destination (mem:BLK ...)
;; 2 = source (mem:BLK ...)
;; 3 = alignment
(define_expand "cmpstrsi"
[(match_operand:HI 0 "" "")
(match_operand 1 "ap_operand" "")
(match_operand 2 "ap_operand" "")
(match_operand 3 "" "")
]
"TARGET_A24"
"if (m32c_expand_cmpstr(operands)) DONE; FAIL;"
)
;; 0 = string1
;; 1 = string2
(define_insn "cmpstrhi_op"
[(set (reg:CC FLG_REGNO)
(compare:CC (mem:BLK (match_operand:PSI 0 "ap_operand" "Ra0"))
(mem:BLK (match_operand:PSI 1 "ap_operand" "Ra1"))))
(clobber (match_operand:PSI 2 "ap_operand" "=0"))
(clobber (match_operand:PSI 3 "ap_operand" "=1"))]
"TARGET_A24"
"scmpu.b\t; flags := strcmp(*%0,*%1)"
[(set_attr "flags" "oszc")]
)
;; Note that SMOVU leaves the address registers pointing *after*
;; the NUL at the end of the string. This is not what gcc expects; it
;; expects the address registers to point *at* the NUL. The expander
;; must emit a suitable add insn.
;; 0 = target: set to &NUL in dest
;; 1 = destination (mem:BLK ...)
;; 2 = source (mem:BLK ...)
(define_expand "movstr"
[(match_operand 0 "" "")
(match_operand 1 "ap_operand" "")
(match_operand 2 "ap_operand" "")
]
"TARGET_A24"
"if (m32c_expand_movstr(operands)) DONE; FAIL;"
)
;; 0 = dest (out)
;; 1 = src (out) (clobbered)
;; 2 = dest (in)
;; 3 = src (in)
(define_insn "movstr_op"
[(set (mem:BLK (match_operand:PSI 2 "ap_operand" "0"))
(mem:BLK (match_operand:PSI 3 "ap_operand" "1")))
(set (match_operand:PSI 0 "ap_operand" "=Ra1")
(plus:PSI (match_dup 2)
(unspec:PSI [(const_int 0)] UNS_SMOVU)))
(set (match_operand:PSI 1 "ap_operand" "=Ra0")
(plus:PSI (match_dup 3)
(unspec:PSI [(const_int 0)] UNS_SMOVU)))]
"TARGET_A24"
"smovu.b\t; while (*%2++ := *%3++) != 0"
[(set_attr "flags" "*")]
)
...@@ -32,41 +32,152 @@ ...@@ -32,41 +32,152 @@
; right flags already. For example, a mov followed by a "cmp *,0" is ; right flags already. For example, a mov followed by a "cmp *,0" is
; redundant; the move already set the Z flag. ; redundant; the move already set the Z flag.
(define_insn "cbranchqi4" (define_insn_and_split "cbranch<mode>4"
[(set (pc) (if_then_else [(set (pc) (if_then_else
(match_operator 0 "m32c_cmp_operator" (match_operator 0 "m32c_cmp_operator"
[(match_operand:QI 1 "mrai_operand" "RqiSd,RqiSd,?Rmm,?Rmm") [(match_operand:QHPSI 1 "mra_operand" "RraSd")
(match_operand:QI 2 "mrai_operand" "iRqiSd,?Rmm,iRqiSd,?Rmm")]) (match_operand:QHPSI 2 "mrai_operand" "iRraSd")])
(label_ref (match_operand 3 "" "")) (label_ref (match_operand 3 "" ""))
(pc)))] (pc)))]
"" ""
"cmp.b\t%2,%1\n\tj%C0\t1f\n\tjmp.a\t%l3\n1:" "#"
; "cmp.b\t%2,%1\n\tj%c0\t%l3" ""
[(set_attr "flags" "oszc,oszc,oszc,oszc")] [(set (reg:CC FLG_REGNO)
(compare (match_dup 1)
(match_dup 2)))
(set (pc) (if_then_else (match_dup 4)
(label_ref (match_dup 3))
(pc)))]
"operands[4] = m32c_cmp_flg_0 (operands[0]);"
) )
(define_insn "cbranchhi4" (define_insn "stzx_16"
[(set (pc) (if_then_else [(set (match_operand:QI 0 "mrai_operand" "=R0w,R0w,R0w")
(match_operator 0 "m32c_cmp_operator" (if_then_else:QI (eq (reg:CC FLG_REGNO) (const_int 0))
[(match_operand:HI 1 "mrai_operand" "Rhi,?Sd,Rhi,?Sd,?Rmm,?Rmm") (match_operand:QI 1 "const_int_operand" "i,i,0")
(match_operand:HI 2 "mrai_operand" "iRhiSd,iRhiSd,?Rmm,?Rmm,iRhiSd,?Rmm")]) (match_operand:QI 2 "const_int_operand" "i,0,i")))]
(label_ref (match_operand 3 "" "")) "TARGET_A16"
(pc)))] "@
stzx\t%1,%2,%0
stz\t%1,%0
stnz\t%2,%0")
(define_insn "stzx_24_<mode>"
[(set (match_operand:QHI 0 "mrai_operand" "=RraSd,RraSd,RraSd")
(if_then_else:QHI (eq (reg:CC FLG_REGNO) (const_int 0))
(match_operand:QHI 1 "const_int_operand" "i,i,0")
(match_operand:QHI 2 "const_int_operand" "i,0,i")))]
"TARGET_A24"
"@
stzx.<bwl>\t%1,%2,%0
stz.<bwl>\t%1,%0
stnz.<bwl>\t%2,%0")
(define_insn_and_split "stzx_reversed"
[(set (match_operand 0 "m32c_r0_operand" "")
(if_then_else (ne (reg:CC FLG_REGNO) (const_int 0))
(match_operand 1 "const_int_operand" "")
(match_operand 2 "const_int_operand" "")))]
"TARGET_A24 || GET_MODE (operands[0]) == QImode"
"#"
""
[(set (match_dup 0)
(if_then_else (eq (reg:CC FLG_REGNO) (const_int 0))
(match_dup 2)
(match_dup 1)))]
"" ""
"cmp.w\t%2,%1\n\tj%C0\t1f\n\tjmp.a\t%l3\n1:"
; "cmp.w\t%2,%1\n\tj%c0\t%l3"
[(set_attr "flags" "oszc,oszc,oszc,oszc,oszc,oszc")]
) )
(define_insn "cbranchpsi4"
[(set (pc) (if_then_else (define_insn "cmp<mode>"
(match_operator 0 "m32c_cmp_operator" [(set (reg:CC FLG_REGNO)
[(match_operand:PSI 1 "mrai_operand" "RsiSd,RsiSd,?Rmm,?Rmm") (compare (match_operand:QHPSI 0 "mra_operand" "RraSd")
(match_operand:PSI 2 "mrai_operand" "iRsiSd,?Rmm,iRsiSd,?Rmm")]) (match_operand:QHPSI 1 "mrai_operand" "RraSdi")))]
(label_ref (match_operand 3 "" "")) ""
"cmp.<bwl>\t%1,%0")
(define_insn "b<code>"
[(set (pc)
(if_then_else (any_cond (reg:CC FLG_REGNO)
(const_int 0))
(label_ref (match_operand 0 ""))
(pc)))] (pc)))]
""
"j<code>\t%l0"
)
;; m32c_conditional_register_usage changes the setcc_gen_code array to
;; point to the _24 variants if needed.
(define_insn "s<code>"
[(set (match_operand:QI 0 "register_operand" "=Rqi")
(any_cond:QI (reg:CC FLG_REGNO) (const_int 0)))]
"TARGET_A16"
"* return m32c_scc_pattern(operands, <CODE>);")
(define_insn "s<code>_24"
[(set (match_operand:HI 0 "mra_operand" "=RhiSd")
(any_cond:HI (reg:CC FLG_REGNO) (const_int 0)))]
"TARGET_A24" "TARGET_A24"
"cmp.l\t%2,%1\n\tj%C0\t1f\n\tjmp.a\t%l3\n1:" "sc<code>\t%0")
; "cmp.l\t%2,%1\n\tj%c0\t%l3"
[(set_attr "flags" "oszc,oszc,oszc,oszc")] (define_expand "movqicc"
[(set (match_operand:QI 0 "register_operand" "")
(if_then_else:QI (match_operand 1 "m32c_eqne_operator" "")
(match_operand:QI 2 "const_int_operand" "")
(match_operand:QI 3 "const_int_operand" "")))]
""
"if (m32c_expand_movcc(operands))
FAIL;
DONE;"
)
(define_expand "movhicc"
[(set (match_operand:HI 0 "mra_operand" "")
(if_then_else:HI (match_operand 1 "m32c_eqne_operator" "")
(match_operand:HI 2 "const_int_operand" "")
(match_operand:HI 3 "const_int_operand" "")))]
"TARGET_A24"
"if (m32c_expand_movcc(operands))
FAIL;
DONE;"
)
;; CMP opcodes subtract two values, set the flags, and discard the
;; value. This pattern recovers the sign of the discarded value based
;; on the flags. Operand 0 is set to -1, 0, or 1. This is used for
;; the cmpstr pattern. For optimal code, this should be removed if
;; followed by a suitable CMP insn, as SCMPU sets the flags correctly
;; already (see the peephole following). This pattern is 7 bytes and
;; 5 cycles. If you don't need specific values, a 5/4 pattern can be
;; made with SCGT and BMLT to set the appropriate bits.
(define_insn "cond_to_int"
[(set (match_operand:HI 0 "mra_qi_operand" "=Rqi")
(if_then_else:HI (lt (reg:CC FLG_REGNO) (const_int 0))
(const_int -1)
(if_then_else:HI (eq (reg:CC FLG_REGNO) (const_int 0))
(const_int 0)
(const_int -1))))]
"TARGET_A24"
"sceq\t%0\n\tbmgt\t1,%h0\n\tdec.w\t%0"
[(set_attr "flags" "sz")]
) )
;; A cond_to_int followed by a compare against zero is essentially a no-op.
(define_peephole2
[(set (match_operand:HI 0 "mra_qi_operand" "")
(if_then_else:HI (lt (reg:CC FLG_REGNO) (const_int 0))
(const_int -1)
(if_then_else:HI (eq (reg:CC FLG_REGNO) (const_int 0))
(const_int 0)
(const_int -1))))
(set (reg:CC FLG_REGNO)
(compare (match_operand:HI 1 "mra_qi_operand" "")
(const_int 0)))
]
"rtx_equal_p(operands[0], operands[1])"
[(const_int 1)]
"")
...@@ -58,8 +58,16 @@ rtx m32c_function_value (tree, tree); ...@@ -58,8 +58,16 @@ rtx m32c_function_value (tree, tree);
int m32c_cannot_change_mode_class (MM, MM, int); int m32c_cannot_change_mode_class (MM, MM, int);
int m32c_class_max_nregs (int, MM); int m32c_class_max_nregs (int, MM);
rtx m32c_cmp_flg_0 (rtx);
rtx m32c_eh_return_stackadj_rtx (void); rtx m32c_eh_return_stackadj_rtx (void);
void m32c_emit_eh_epilogue (rtx); void m32c_emit_eh_epilogue (rtx);
int m32c_expand_cmpstr (rtx *);
int m32c_expand_insv (rtx *);
int m32c_expand_movcc (rtx *);
int m32c_expand_movmemhi (rtx *);
int m32c_expand_movstr (rtx *);
void m32c_expand_neg_mulpsi3 (rtx *);
int m32c_expand_setmemhi (rtx *);
int m32c_extra_constraint_p (rtx, char, const char *); int m32c_extra_constraint_p (rtx, char, const char *);
int m32c_extra_constraint_p2 (rtx, char, const char *); int m32c_extra_constraint_p2 (rtx, char, const char *);
int m32c_hard_regno_nregs (int, MM); int m32c_hard_regno_nregs (int, MM);
...@@ -86,6 +94,7 @@ int m32c_reg_ok_for_base_p (rtx, int); ...@@ -86,6 +94,7 @@ int m32c_reg_ok_for_base_p (rtx, int);
int m32c_register_move_cost (MM, int, int); int m32c_register_move_cost (MM, int, int);
MM m32c_regno_reg_class (int); MM m32c_regno_reg_class (int);
rtx m32c_return_addr_rtx (int); rtx m32c_return_addr_rtx (int);
const char *m32c_scc_pattern (rtx *, RTX_CODE);
int m32c_secondary_reload_class (int, MM, rtx); int m32c_secondary_reload_class (int, MM, rtx);
int m32c_split_move (rtx *, MM, int); int m32c_split_move (rtx *, MM, int);
int m32c_split_psi_p (rtx *); int m32c_split_psi_p (rtx *);
......
...@@ -261,10 +261,12 @@ machine_function; ...@@ -261,10 +261,12 @@ machine_function;
{ 0x0000000a }, /* R23 - r2 r3 */\ { 0x0000000a }, /* R23 - r2 r3 */\
{ 0x0000000f }, /* R03 - r0r2 r1r3 */\ { 0x0000000f }, /* R03 - r0r2 r1r3 */\
{ 0x0000000f }, /* DI - r0r2r1r3 + mems */\ { 0x0000000f }, /* DI - r0r2r1r3 + mems */\
{ 0x00000010 }, /* A0 - a0 */\
{ 0x00000020 }, /* A1 - a1 */\
{ 0x00000030 }, /* A - a0 a1 */\ { 0x00000030 }, /* A - a0 a1 */\
{ 0x000000f0 }, /* AD - a0 a1 sb fp */\ { 0x000000f0 }, /* AD - a0 a1 sb fp */\
{ 0x000001f0 }, /* PS - a0 a1 sb fp sp */\ { 0x000001f0 }, /* PS - a0 a1 sb fp sp */\
{ 0x0000003f }, /* SI - r0r2 r1r3 a0a1 */\ { 0x0000000f }, /* SI - r0r2 r1r3 a0a1 */\
{ 0x0000003f }, /* HI - r0 r1 r2 r3 a0 a1 */\ { 0x0000003f }, /* HI - r0 r1 r2 r3 a0 a1 */\
{ 0x0000003f }, /* RA - r0..r3 a0 a1 */\ { 0x0000003f }, /* RA - r0..r3 a0 a1 */\
{ 0x0000007f }, /* GENERAL */\ { 0x0000007f }, /* GENERAL */\
...@@ -297,6 +299,8 @@ enum reg_class ...@@ -297,6 +299,8 @@ enum reg_class
R23_REGS, R23_REGS,
R03_REGS, R03_REGS,
DI_REGS, DI_REGS,
A0_REGS,
A1_REGS,
A_REGS, A_REGS,
AD_REGS, AD_REGS,
PS_REGS, PS_REGS,
...@@ -335,6 +339,8 @@ enum reg_class ...@@ -335,6 +339,8 @@ enum reg_class
"R23_REGS", \ "R23_REGS", \
"R03_REGS", \ "R03_REGS", \
"DI_REGS", \ "DI_REGS", \
"A0_REGS", \
"A1_REGS", \
"A_REGS", \ "A_REGS", \
"AD_REGS", \ "AD_REGS", \
"PS_REGS", \ "PS_REGS", \
...@@ -656,6 +662,8 @@ typedef struct m32c_cumulative_args ...@@ -656,6 +662,8 @@ typedef struct m32c_cumulative_args
#define MOVE_MAX 4 #define MOVE_MAX 4
#define TRULY_NOOP_TRUNCATION(op,ip) 1 #define TRULY_NOOP_TRUNCATION(op,ip) 1
#define STORE_FLAG_VALUE 1
/* 16 or 24 bit pointers */ /* 16 or 24 bit pointers */
#define Pmode (TARGET_A16 ? HImode : PSImode) #define Pmode (TARGET_A16 ? HImode : PSImode)
#define FUNCTION_MODE QImode #define FUNCTION_MODE QImode
......
...@@ -44,14 +44,35 @@ ...@@ -44,14 +44,35 @@
(UNS_EH_EPILOGUE 3) (UNS_EH_EPILOGUE 3)
(UNS_PUSHM 4) (UNS_PUSHM 4)
(UNS_POPM 5) (UNS_POPM 5)
(UNS_SMOVF 6)
(UNS_SSTR 7)
(UNS_SCMPU 8)
(UNS_SMOVU 9)
]) ])
;; n = no change, x = clobbered. The first 16 values are chosen such
;; that the enum has one bit set for each flag.
(define_attr "flags" "x,c,z,zc,s,sc,sz,szc,o,oc,oz,ozc,os,osc,osz,oszc,n" (const_string "n"))
(define_asm_attributes [(set_attr "flags" "x")])
(define_mode_macro QHI [QI HI])
(define_mode_macro HPSI [(HI "TARGET_A16") (PSI "TARGET_A24")])
(define_mode_macro QHPSI [QI HI (PSI "TARGET_A24")])
(define_mode_macro QHSI [QI HI (SI "TARGET_A24")])
(define_mode_attr bwl [(QI "b") (HI "w") (PSI "l") (SI "l")])
(define_code_macro any_cond [eq ne gt ge lt le gtu geu ltu leu])
(define_code_macro eqne_cond [eq ne])
(define_code_macro gl_cond [gt ge lt le gtu geu ltu leu])
(define_insn "nop" (define_insn "nop"
[(const_int 0)] [(const_int 0)]
"" ""
"nop") "nop")
;; n = no change, x = clobbered. The first 16 values are chosen such (define_insn "no_insn"
;; that the enum has one bit set for each flag. [(const_int 1)]
(define_attr "flags" "x,c,z,zc,s,sc,sz,szc,o,oc,oz,ozc,os,osc,osz,oszc,n" (const_string "n")) ""
(define_asm_attributes [(set_attr "flags" "x")]) "")
...@@ -32,9 +32,9 @@ ...@@ -32,9 +32,9 @@
;; Match push/pop before mov.b for passing char as arg, ;; Match push/pop before mov.b for passing char as arg,
;; e.g. stdlib/efgcvt.c. ;; e.g. stdlib/efgcvt.c.
(define_insn "movqi_op" (define_insn "movqi_op"
[(set (match_operand:QI 0 "mra_qi_operand" [(set (match_operand:QI 0 "m32c_nonimmediate_operand"
"=Rqi*Rmm, <, RqiSd*Rmm, SdSs, Rqi*Rmm, Sd") "=Rqi*Rmm, <, RqiSd*Rmm, SdSs, Rqi*Rmm, Sd")
(match_operand:QI 1 "mrai_qi_operand" (match_operand:QI 1 "m32c_any_operand"
"iRqi*Rmm, iRqiSd*Rmm, >, Rqi*Rmm, SdSs, i"))] "iRqi*Rmm, iRqiSd*Rmm, >, Rqi*Rmm, SdSs, i"))]
"m32c_mov_ok (operands, QImode)" "m32c_mov_ok (operands, QImode)"
"@ "@
...@@ -48,17 +48,17 @@ ...@@ -48,17 +48,17 @@
) )
(define_expand "movqi" (define_expand "movqi"
[(set (match_operand:QI 0 "mra_qi_operand" "=RqiSd*Rmm") [(set (match_operand:QI 0 "nonimmediate_operand" "=RqiSd*Rmm")
(match_operand:QI 1 "mrai_qi_operand" "iRqiSd*Rmm"))] (match_operand:QI 1 "general_operand" "iRqiSd*Rmm"))]
"" ""
"if (m32c_prepare_move (operands, QImode)) DONE;" "if (m32c_prepare_move (operands, QImode)) DONE;"
) )
(define_insn "movhi_op" (define_insn "movhi_op"
[(set (match_operand:HI 0 "nonimmediate_operand" [(set (match_operand:HI 0 "m32c_nonimmediate_operand"
"=Rhi*Rmm, Sd, SdSs, *Rcr, RhiSd*Rmm, <, RhiSd*Rmm, <, *Rcr") "=Rhi*Rmm, Sd, SdSs, *Rcr, RhiSd*Rmm, <, RhiSd*Rmm, <, *Rcr")
(match_operand:HI 1 "general_operand" (match_operand:HI 1 "m32c_any_operand"
"iRhi*RmmSdSs, i, Rhi*Rmm, RhiSd*Rmm, *Rcr, iRhiSd*Rmm, >, *Rcr, >"))] "iRhi*RmmSdSs, i, Rhi*Rmm, RhiSd*Rmm, *Rcr, iRhiSd*Rmm, >, *Rcr, >"))]
"m32c_mov_ok (operands, HImode)" "m32c_mov_ok (operands, HImode)"
"@ "@
...@@ -75,18 +75,18 @@ ...@@ -75,18 +75,18 @@
) )
(define_expand "movhi" (define_expand "movhi"
[(set (match_operand:HI 0 "nonimmediate_operand" "=RhiSd*Rmm") [(set (match_operand:HI 0 "m32c_nonimmediate_operand" "=RhiSd*Rmm")
(match_operand:HI 1 "general_operand" "iRhiSd*Rmm"))] (match_operand:HI 1 "m32c_any_operand" "iRhiSd*Rmm"))]
"" ""
"if (m32c_prepare_move (operands, HImode)) DONE;" "if (m32c_prepare_move (operands, HImode)) DONE;"
) )
(define_insn "movpsi_op" (define_insn "movpsi_op"
[(set (match_operand:PSI 0 "nonimmediate_operand" [(set (match_operand:PSI 0 "m32c_nonimmediate_operand"
"=Raa, SdRmmRpi, Rcl, RpiSd*Rmm, <, <, Rcl, Rsi*Rmm") "=Raa, SdRmmRpi, Rcl, RpiSd*Rmm, <, <, Rcl, RpiRaa*Rmm")
(match_operand:PSI 1 "general_operand" (match_operand:PSI 1 "m32c_any_operand"
"sIU3, iSdRmmRpi, iRpiSd*Rmm, Rcl, Rsi*Rmm, Rcl, >, >"))] "sIU3, iSdRmmRpi, iRpiSd*Rmm, Rcl, Rpi*Rmm, Rcl, >, >"))]
"TARGET_A24 && m32c_mov_ok (operands, PSImode)" "TARGET_A24 && m32c_mov_ok (operands, PSImode)"
"@ "@
mov.l:s\t%1,%0 mov.l:s\t%1,%0
...@@ -104,9 +104,6 @@ ...@@ -104,9 +104,6 @@
;; The intention here is to combine the add with the move to create an ;; The intention here is to combine the add with the move to create an
;; indexed move. GCC doesn't always figure this out itself. ;; indexed move. GCC doesn't always figure this out itself.
(define_mode_macro QHSI [QI HI SI])
(define_mode_macro HPSI [(HI "TARGET_A16") (PSI "TARGET_A24")])
(define_peephole2 (define_peephole2
[(set (match_operand:HPSI 0 "register_operand" "") [(set (match_operand:HPSI 0 "register_operand" "")
(plus:HPSI (match_operand:HPSI 1 "register_operand" "") (plus:HPSI (match_operand:HPSI 1 "register_operand" "")
...@@ -128,7 +125,7 @@ ...@@ -128,7 +125,7 @@
(plus:HPSI (match_operand:HPSI 1 "register_operand" "") (plus:HPSI (match_operand:HPSI 1 "register_operand" "")
(match_operand:HPSI 2 "immediate_operand" ""))) (match_operand:HPSI 2 "immediate_operand" "")))
(set (mem:QHSI (match_operand:HPSI 4 "register_operand" "")) (set (mem:QHSI (match_operand:HPSI 4 "register_operand" ""))
(match_operand:QHSI 3 "general_operand" ""))] (match_operand:QHSI 3 "m32c_any_operand" ""))]
"REGNO (operands[0]) == REGNO (operands[1]) "REGNO (operands[0]) == REGNO (operands[1])
&& REGNO (operands[0]) == REGNO (operands[4]) && REGNO (operands[0]) == REGNO (operands[4])
&& dead_or_set_p (peep2_next_insn (1), operands[4]) && dead_or_set_p (peep2_next_insn (1), operands[4])
...@@ -141,8 +138,8 @@ ...@@ -141,8 +138,8 @@
; Some PSI moves must be split. ; Some PSI moves must be split.
(define_split (define_split
[(set (match_operand:PSI 0 "nonimmediate_operand" "") [(set (match_operand:PSI 0 "m32c_nonimmediate_operand" "")
(match_operand:PSI 1 "general_operand" ""))] (match_operand:PSI 1 "m32c_any_operand" ""))]
"reload_completed && m32c_split_psi_p (operands)" "reload_completed && m32c_split_psi_p (operands)"
[(set (match_dup 2) [(set (match_dup 2)
(match_dup 3)) (match_dup 3))
...@@ -152,8 +149,8 @@ ...@@ -152,8 +149,8 @@
) )
(define_expand "movpsi" (define_expand "movpsi"
[(set (match_operand:PSI 0 "mras_operand" "") [(set (match_operand:PSI 0 "m32c_nonimmediate_operand" "")
(match_operand:PSI 1 "mrasi_operand" ""))] (match_operand:PSI 1 "m32c_any_operand" ""))]
"" ""
"if (m32c_prepare_move (operands, PSImode)) DONE;" "if (m32c_prepare_move (operands, PSImode)) DONE;"
) )
...@@ -161,16 +158,16 @@ ...@@ -161,16 +158,16 @@
(define_expand "movsi" (define_expand "movsi"
[(set (match_operand:SI 0 "mras_operand" "=RsiSd*Rmm") [(set (match_operand:SI 0 "m32c_nonimmediate_operand" "=RsiSd*Rmm")
(match_operand:SI 1 "mrasi_operand" "iRsiSd*Rmm"))] (match_operand:SI 1 "m32c_any_operand" "iRsiSd*Rmm"))]
"" ""
"if (m32c_split_move (operands, SImode, 0)) DONE;" "if (m32c_split_move (operands, SImode, 0)) DONE;"
) )
; All SI moves are split if TARGET_A16 ; All SI moves are split if TARGET_A16
(define_insn_and_split "movsi_splittable" (define_insn_and_split "movsi_splittable"
[(set (match_operand:SI 0 "mras_operand" "=Rsi<*Rmm,RsiSd*Rmm,Ss") [(set (match_operand:SI 0 "m32c_nonimmediate_operand" "=Rsi<*Rmm,RsiSd*Rmm,Ss")
(match_operand:SI 1 "mrasi_operand" "iRsiSd*Rmm,iRsi>*Rmm,Rsi*Rmm"))] (match_operand:SI 1 "m32c_any_operand" "iRsiSd*Rmm,iRsi>*Rmm,Rsi*Rmm"))]
"TARGET_A16" "TARGET_A16"
"#" "#"
"TARGET_A16 && reload_completed" "TARGET_A16 && reload_completed"
...@@ -182,14 +179,14 @@ ...@@ -182,14 +179,14 @@
; don't match. ; don't match.
(define_insn "push_a01_l" (define_insn "push_a01_l"
[(set (mem:SI (pre_dec:PSI (reg:PSI SP_REGNO))) [(set (mem:SI (pre_dec:PSI (reg:PSI SP_REGNO)))
(match_operand 0 "a_operand" ""))] (match_operand 0 "a_operand" "Raa"))]
"" ""
"push.l\t%0" "push.l\t%0"
) )
(define_insn "movsi_24" (define_insn "movsi_24"
[(set (match_operand:SI 0 "mras_operand" "=Rsi*Rmm, Sd, RsiSd*Rmm, <") [(set (match_operand:SI 0 "m32c_nonimmediate_operand" "=Rsi*Rmm, Sd, RsiSd*Rmm, <")
(match_operand:SI 1 "mrasi_operand" "iRsiSd*Rmm, iRsi*Rmm, >, iRsiRaaSd*Rmm"))] (match_operand:SI 1 "m32c_any_operand" "iRsiSd*Rmm, iRsi*Rmm, >, iRsiRaaSd*Rmm"))]
"TARGET_A24" "TARGET_A24"
"@ "@
mov.l\t%1,%0 mov.l\t%1,%0
...@@ -199,15 +196,15 @@ ...@@ -199,15 +196,15 @@
) )
(define_expand "movdi" (define_expand "movdi"
[(set (match_operand:DI 0 "mras_operand" "=RdiSd*Rmm") [(set (match_operand:DI 0 "m32c_nonimmediate_operand" "=RdiSd*Rmm")
(match_operand:DI 1 "mrasi_operand" "iRdiSd*Rmm"))] (match_operand:DI 1 "m32c_any_operand" "iRdiSd*Rmm"))]
"" ""
"if (m32c_split_move (operands, DImode, 0)) DONE;" "if (m32c_split_move (operands, DImode, 0)) DONE;"
) )
(define_insn_and_split "movdi_splittable" (define_insn_and_split "movdi_splittable"
[(set (match_operand:DI 0 "mras_operand" "=Rdi<*Rmm,RdiSd*Rmm") [(set (match_operand:DI 0 "m32c_nonimmediate_operand" "=Rdi<*Rmm,RdiSd*Rmm")
(match_operand:DI 1 "mrasi_operand" "iRdiSd*Rmm,iRdi>*Rmm"))] (match_operand:DI 1 "m32c_any_operand" "iRdiSd*Rmm,iRdi>*Rmm"))]
"" ""
"#" "#"
"reload_completed" "reload_completed"
...@@ -305,7 +302,7 @@ ...@@ -305,7 +302,7 @@
;; Rhl used here as an HI-mode Rxl ;; Rhl used here as an HI-mode Rxl
(define_insn "extendqihi2" (define_insn "extendqihi2"
[(set (match_operand:HI 0 "mra_operand" "=RhlSd*Rmm") [(set (match_operand:HI 0 "m32c_nonimmediate_operand" "=RhlSd*Rmm")
(sign_extend:HI (match_operand:QI 1 "mra_operand" "0")))] (sign_extend:HI (match_operand:QI 1 "mra_operand" "0")))]
"" ""
"exts.b\t%1" "exts.b\t%1"
...@@ -313,7 +310,7 @@ ...@@ -313,7 +310,7 @@
) )
(define_insn "extendhisi2" (define_insn "extendhisi2"
[(set (match_operand:SI 0 "r0123_operand" "=R03") [(set (match_operand:SI 0 "register_operand" "=R03")
(sign_extend:SI (match_operand:HI 1 "r0123_operand" "0")))] (sign_extend:SI (match_operand:HI 1 "r0123_operand" "0")))]
"" ""
"* "*
...@@ -337,28 +334,30 @@ ...@@ -337,28 +334,30 @@
) )
(define_insn "zero_extendhipsi2" (define_insn "zero_extendhipsi2"
[(set (match_operand:PSI 0 "nonimmediate_operand" "=Raa") [(set (match_operand:PSI 0 "register_operand" "=Raa")
(truncate:PSI (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "Rhi"))))] (truncate:PSI (zero_extend:SI (match_operand:HI 1 "register_operand" "R03"))))]
"" ""
"mov.w\t%1,%0" "mov.w\t%1,%0"
) )
(define_insn "zero_extendhisi2" (define_insn "zero_extendhisi2"
[(set (match_operand:SI 0 "nonimmediate_operand" "=RsiSd") [(set (match_operand:SI 0 "m32c_nonimmediate_operand" "=RsiSd")
(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")))] (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")))]
"" ""
"mov.w\t#0,%H0" "mov.w\t#0,%H0"
) )
(define_insn "zero_extendqihi2" (define_insn "zero_extendqihi2"
[(set (match_operand:HI 0 "nonimmediate_operand" "=RsiRaaSd*Rmm") [(set (match_operand:HI 0 "m32c_nonimmediate_operand" "=Rhl,RhiSd*Rmm")
(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0")))] (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
"" ""
"and.w\t#255,%0" "@
mov.b\t#0,%H0
and.w\t#255,%0"
) )
(define_insn "truncsipsi2_16" (define_insn "truncsipsi2_16"
[(set (match_operand:PSI 0 "nonimmediate_operand" "=RsiRadSd*Rmm,Raa,Rcr,RsiSd*Rmm") [(set (match_operand:PSI 0 "m32c_nonimmediate_operand" "=RsiRadSd*Rmm,Raa,Rcr,RsiSd*Rmm")
(truncate:PSI (match_operand:SI 1 "nonimmediate_operand" "0,RsiSd*Rmm,RsiSd*Rmm,Rcr")))] (truncate:PSI (match_operand:SI 1 "nonimmediate_operand" "0,RsiSd*Rmm,RsiSd*Rmm,Rcr")))]
"TARGET_A16" "TARGET_A16"
"@ "@
...@@ -369,15 +368,15 @@ ...@@ -369,15 +368,15 @@
) )
(define_insn "trunchiqi2" (define_insn "trunchiqi2"
[(set (match_operand:QI 0 "mra_qi_operand" "=RqiRmmSd") [(set (match_operand:QI 0 "m32c_nonimmediate_operand" "=RqiRmmSd")
(truncate:QI (match_operand:HI 1 "mra_qi_operand" "0")))] (truncate:QI (match_operand:HI 1 "mra_qi_operand" "0")))]
"" ""
"; no-op trunc hi %1 to qi %0" "; no-op trunc hi %1 to qi %0"
) )
(define_insn "truncsipsi2_24" (define_insn "truncsipsi2_24"
[(set (match_operand:PSI 0 "nonimmediate_operand" "=RsiSd*Rmm,Raa,!Rcl,RsiSd*Rmm") [(set (match_operand:PSI 0 "m32c_nonimmediate_operand" "=RsiSd*Rmm,Raa,!Rcl,RsiSd*Rmm")
(truncate:PSI (match_operand:SI 1 "nonimmediate_operand" "0,RsiSd*Rmm,RsiSd*Rmm,!Rcl")))] (truncate:PSI (match_operand:SI 1 "m32c_nonimmediate_operand" "0,RsiSd*Rmm,RsiSd*Rmm,!Rcl")))]
"TARGET_A24" "TARGET_A24"
"@ "@
; no-op trunc si %1 to psi %0 ; no-op trunc si %1 to psi %0
...@@ -387,8 +386,8 @@ ...@@ -387,8 +386,8 @@
) )
(define_expand "truncsipsi2" (define_expand "truncsipsi2"
[(set (match_operand:PSI 0 "nonimmediate_operand" "=RsiRadSd*Rmm,Raa,Rcr,RsiSd*Rmm") [(set (match_operand:PSI 0 "m32c_nonimmediate_operand" "=RsiRadSd*Rmm,Raa,Rcr,RsiSd*Rmm")
(truncate:PSI (match_operand:SI 1 "nonimmediate_operand" "0,RsiSd*Rmm,RsiSd*Rmm,Rcr")))] (truncate:PSI (match_operand:SI 1 "m32c_nonimmediate_operand" "0,RsiSd*Rmm,RsiSd*Rmm,Rcr")))]
"" ""
"" ""
) )
......
...@@ -143,7 +143,8 @@ ...@@ -143,7 +143,8 @@
(mult:PSI (match_operand:PSI 1 "mra_operand" "%0") (mult:PSI (match_operand:PSI 1 "mra_operand" "%0")
(match_operand 2 "m32c_psi_scale" "Ilb")))] (match_operand 2 "m32c_psi_scale" "Ilb")))]
"TARGET_A24" "TARGET_A24"
"if (INTVAL(operands[2]) < 0) "if (GET_CODE (operands[2]) != CONST_INT
|| INTVAL(operands[2]) < 0)
{ {
m32c_expand_neg_mulpsi3 (operands); m32c_expand_neg_mulpsi3 (operands);
DONE; DONE;
......
...@@ -22,6 +22,19 @@ ...@@ -22,6 +22,19 @@
;; Predicates ;; Predicates
; TRUE for any valid operand. We do this because general_operand
; refuses to match volatile memory refs.
(define_predicate "m32c_any_operand"
(ior (match_operand 0 "general_operand")
(match_operand 1 "memory_operand")))
; Likewise for nonimmediate_operand.
(define_predicate "m32c_nonimmediate_operand"
(ior (match_operand 0 "nonimmediate_operand")
(match_operand 1 "memory_operand")))
; TRUE if the operand is a pseudo-register. ; TRUE if the operand is a pseudo-register.
(define_predicate "m32c_pseudo" (define_predicate "m32c_pseudo"
(ior (and (match_code "reg") (ior (and (match_code "reg")
...@@ -63,12 +76,25 @@ ...@@ -63,12 +76,25 @@
(and (match_code "reg") (and (match_code "reg")
(match_test "REGNO(op) == R1_REGNO")))) (match_test "REGNO(op) == R1_REGNO"))))
; TRUE for HL_CLASS (r0 or r1)
(define_predicate "m32c_hl_operand"
(ior (match_operand 0 "m32c_pseudo" "")
(and (match_code "reg")
(match_test "REGNO(op) == R0_REGNO || REGNO(op) == R1_REGNO"))))
; TRUE for r2 ; TRUE for r2
(define_predicate "m32c_r2_operand" (define_predicate "m32c_r2_operand"
(ior (match_operand 0 "m32c_pseudo" "") (ior (match_operand 0 "m32c_pseudo" "")
(and (match_code "reg") (and (match_code "reg")
(match_test "REGNO(op) == R2_REGNO")))) (match_test "REGNO(op) == R2_REGNO"))))
; TRUE for r3
(define_predicate "m32c_r3_operand"
(ior (match_operand 0 "m32c_pseudo" "")
(and (match_code "reg")
(match_test "REGNO(op) == R3_REGNO"))))
; TRUE for any general operand except r2. ; TRUE for any general operand except r2.
(define_predicate "m32c_notr2_operand" (define_predicate "m32c_notr2_operand"
(and (match_operand 0 "general_operand") (and (match_operand 0 "general_operand")
...@@ -89,9 +115,14 @@ ...@@ -89,9 +115,14 @@
; TRUE for $a0 or $a1. ; TRUE for $a0 or $a1.
(define_predicate "a_operand" (define_predicate "a_operand"
(match_code "reg") (and (match_code "reg")
"return (REGNO (op) == A0_REGNO (match_test "REGNO (op) == A0_REGNO || REGNO (op) == A1_REGNO")))
|| REGNO (op) == A1_REGNO);")
; TRUE for $a0 or $a1 or a pseudo
(define_predicate "ap_operand"
(ior (match_operand 0 "m32c_pseudo" "")
(and (match_code "reg")
(match_test "REGNO (op) == A0_REGNO || REGNO (op) == A1_REGNO"))))
; TRUE for r0 through r3, or a0 or a1. ; TRUE for r0 through r3, or a0 or a1.
(define_predicate "ra_operand" (define_predicate "ra_operand"
...@@ -112,7 +143,7 @@ ...@@ -112,7 +143,7 @@
; TRUE for memory, r0..r3, a0..a1, or immediates. ; TRUE for memory, r0..r3, a0..a1, or immediates.
(define_predicate "mrai_operand" (define_predicate "mrai_operand"
(and (and (match_operand 0 "general_operand" "") (and (and (match_operand 0 "m32c_any_operand" "")
(not (match_operand 1 "cr_operand" ""))) (not (match_operand 1 "cr_operand" "")))
(not (match_operand 2 "m32c_wide_subreg" "")))) (not (match_operand 2 "m32c_wide_subreg" ""))))
...@@ -126,7 +157,22 @@ ...@@ -126,7 +157,22 @@
(and (match_operand 0 "mra_operand" "") (and (match_operand 0 "mra_operand" "")
(not (match_operand 1 "a_operand" "")))) (not (match_operand 1 "a_operand" ""))))
; TRUE for r1h. This complicated since r1h isn't a register GCC ; TRUE for a0..a1 or memory.
(define_predicate "ma_operand"
(ior (match_operand 0 "a_operand" "")
(match_operand 1 "memory_operand" "")))
; TRUE for memory operands that are not indexed
(define_predicate "memsym_operand"
(and (match_operand 0 "memory_operand" "")
(match_test "m32c_extra_constraint_p (op, 'S', \"Si\")")))
; TRUE for memory operands with small integer addresses
(define_predicate "memimmed_operand"
(and (match_operand 0 "memory_operand" "")
(match_test "m32c_extra_constraint_p (op, 'S', \"Sp\")")))
; TRUE for r1h. This is complicated since r1h isn't a register GCC
; normally knows about. ; normally knows about.
(define_predicate "r1h_operand" (define_predicate "r1h_operand"
(match_code "zero_extract") (match_code "zero_extract")
...@@ -175,19 +221,26 @@ ...@@ -175,19 +221,26 @@
; These two are only for movqi - no subreg limit ; These two are only for movqi - no subreg limit
(define_predicate "mra_qi_operand" (define_predicate "mra_qi_operand"
(and (and (match_operand 0 "nonimmediate_operand" "") (and (and (match_operand 0 "m32c_nonimmediate_operand" "")
(not (match_operand 1 "cr_operand" ""))) (not (match_operand 1 "cr_operand" "")))
(not (match_operand 1 "m32c_r2r3a_operand" "")))) (not (match_operand 1 "m32c_r2r3a_operand" ""))))
(define_predicate "mrai_qi_operand" (define_predicate "mrai_qi_operand"
(and (and (match_operand 0 "general_operand" "") (and (and (match_operand 0 "m32c_any_operand" "")
(not (match_operand 1 "cr_operand" ""))) (not (match_operand 1 "cr_operand" "")))
(not (match_operand 1 "m32c_r2r3a_operand" "")))) (not (match_operand 1 "m32c_r2r3a_operand" ""))))
(define_predicate "a_qi_operand"
(ior (match_operand 0 "m32c_pseudo" "")
(match_operand 1 "a_operand" "")))
; TRUE for comparisons we support. ; TRUE for comparisons we support.
(define_predicate "m32c_cmp_operator" (define_predicate "m32c_cmp_operator"
(match_code "eq,ne,gt,gtu,lt,ltu,ge,geu,le,leu")) (match_code "eq,ne,gt,gtu,lt,ltu,ge,geu,le,leu"))
(define_predicate "m32c_eqne_operator"
(match_code "eq,ne"))
; TRUE for mem0 ; TRUE for mem0
(define_predicate "m32c_mem0_operand" (define_predicate "m32c_mem0_operand"
(ior (match_operand 0 "m32c_pseudo" "") (ior (match_operand 0 "m32c_pseudo" "")
...@@ -204,3 +257,21 @@ ...@@ -204,3 +257,21 @@
(define_predicate "m32c_psi_scale" (define_predicate "m32c_psi_scale"
(and (match_operand 0 "const_int_operand") (and (match_operand 0 "const_int_operand")
(match_test "m32c_const_ok_for_constraint_p(INTVAL(op), 'I', \"Ilb\")"))) (match_test "m32c_const_ok_for_constraint_p(INTVAL(op), 'I', \"Ilb\")")))
; TRUE for one bit set (bit) or clear (mask) out of N bits.
(define_predicate "m32c_1bit8_operand"
(and (match_operand 0 "const_int_operand")
(match_test "m32c_const_ok_for_constraint_p(INTVAL(op), 'I', \"Ilb\")")))
(define_predicate "m32c_1bit16_operand"
(and (match_operand 0 "const_int_operand")
(match_test "m32c_const_ok_for_constraint_p(INTVAL(op), 'I', \"Ilw\")")))
(define_predicate "m32c_1mask8_operand"
(and (match_operand 0 "const_int_operand")
(match_test "m32c_const_ok_for_constraint_p(INTVAL(op), 'I', \"Imb\")")))
(define_predicate "m32c_1mask16_operand"
(and (match_operand 0 "const_int_operand")
(match_test "m32c_const_ok_for_constraint_p(INTVAL(op), 'I', \"Imw\")")))
...@@ -48,7 +48,7 @@ dp-bit.c: $(srcdir)/config/fp-bit.c ...@@ -48,7 +48,7 @@ dp-bit.c: $(srcdir)/config/fp-bit.c
md_file = md md_file = md
MD_FILES = m32c predicates addsub bitops cond jump minmax mov muldiv prologue shift MD_FILES = m32c predicates addsub bitops blkmov cond jump minmax mov muldiv prologue shift
# Doing it this way lets the gen* programs report the right line numbers. # Doing it this way lets the gen* programs report the right line numbers.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment