diff options
author | Jeff Law <law@gcc.gnu.org> | 1996-04-28 23:27:26 -0600 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 1996-04-28 23:27:26 -0600 |
commit | bd93f126954387c1e553202c75fb3c9a6f981315 (patch) | |
tree | f890c366b72af7d227b238f089c6ad3460b98b21 /gcc | |
parent | 2ac42d3ac2e7382a35b5bf82be9fda8fa1854520 (diff) | |
download | gcc-bd93f126954387c1e553202c75fb3c9a6f981315.zip gcc-bd93f126954387c1e553202c75fb3c9a6f981315.tar.gz gcc-bd93f126954387c1e553202c75fb3c9a6f981315.tar.bz2 |
h8300.c (names_small): Remove "BAD" postfix from %r7 byte registers.
* h8300/h8300.c (names_small): Remove "BAD" postfix from
%r7 byte registers.
(rtx_equal_function_value_matters): Remove extra declaration.
(output_simode_bld): New function.
* h8300/h8300.h (NO_FUNCTION_CSE): Do define this. Register
pressure makes cse-int function addresses rarely a win.
(reg_class): Remove unnecessary register classes LONG_REGS,
SP_REG, SP_AND_G_REGS.
(REG_CLASS_NAMES): Corresponding changes.
(REG_CLASS_CONTENTS): Corresponding changes.
(REGNO_REG_CLASS): Corresponding changes.
(REG_CLASS_FROM_LETTER): Corresponding chagnes.
(output_simode_bld): Declare.
* h8300/h8300.md: Nuke comments for stuff which has been fixed.
(all patterns): Remove references to register class "a" (SP_REGS)
which no longer exists.
(many patterns): Accept auto-inc auto-dec addresses in more cases.
(zero_extendqisi2): New pattern for the H8/300.
(zero_extendhisi2): Only use zero_extendhisi2_h8300 when not optimizing.
(extendhisi2): Only use extendhisi2_h8300 when not optimizing.
(extendqisi2): New pattern for the H8/300.
(bitfield related patterns): Completely rewrite.
(fancy_bclr, fancy_btst): Deleted. Redundant with new bitfield
patterns.
(addhi3 pattern for h8300): Handle case where we can't make matching
constraints (works around hard to fix reload problem).
(stack_pointer_manip): Delete.
(and not patterns): New combiner patterns.
From-SVN: r11902
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/h8300/h8300.c | 30 | ||||
-rw-r--r-- | gcc/config/h8300/h8300.h | 38 | ||||
-rw-r--r-- | gcc/config/h8300/h8300.md | 736 |
3 files changed, 467 insertions, 337 deletions
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index 6b0d285..0bca23f 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -104,7 +104,7 @@ byte_reg (x, b) { static char *names_small[] = {"r0l", "r0h", "r1l", "r1h", "r2l", "r2h", "r3l", "r3h", - "r4l", "r4h", "r5l", "r5h", "r6l", "r6h", "r7lBAD", "r7hBAD"}; + "r4l", "r4h", "r5l", "r5h", "r6l", "r6h", "r7l", "r7h"}; return names_small[REGNO (x) * 2 + b]; } @@ -1545,8 +1545,6 @@ expand_a_shift (mode, code, operands) int code; rtx operands[]; { - extern int rtx_equal_function_value_matters; - emit_move_insn (operands[0], operands[1]); /* need a loop to get all the bits we want - we generate the @@ -2229,3 +2227,29 @@ h8300_valid_machine_decl_attribute (decl, attributes, attr, args) return 0; } +char * +output_simode_bld (bild, log2, operands) + int bild; + int log2; + rtx operands[]; +{ + /* Clear the destination register. */ + if (TARGET_H8300H) + output_asm_insn ("sub.l\t%S0,%S0", operands); + else + output_asm_insn ("sub.w\t%e0,%e0\n\tsub.w\t%f0,%f0", operands); + + /* Get the bit number we want to load. */ + if (log2) + operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2]))); + + /* Now output the bit load or bit inverse load, and store it in + the destination. */ + if (bild) + output_asm_insn ("bild\t%Z2,%Y1\n\tbst\t#0,%w0", operands); + else + output_asm_insn ("bld\t%Z2,%Y1\n\tbst\t#0,%w0", operands); + + /* All done. */ + return ""; +} diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h index a5544d9..aa87769 100644 --- a/gcc/config/h8300/h8300.h +++ b/gcc/config/h8300/h8300.h @@ -125,8 +125,12 @@ do { \ /* Define this if addresses of constant functions shouldn't be put through pseudo regs where they can be cse'd. Desirable on machines where ordinary constants are expensive - but a CALL with constant address is cheap. */ -/* #define NO_FUNCTION_CSE */ + but a CALL with constant address is cheap. + + Calls through a register are cheaper than calls to named + functions; however, the register pressure this causes makes + CSEing of function addresses generally a lose. */ +#define NO_FUNCTION_CSE /* Target machine storage layout */ @@ -319,12 +323,8 @@ do { \ For any two classes, it is very desirable that there be another class that represents their union. */ -/* The h8 has only one kind of register, but we mustn't do byte by - byte operations on the sp, so we keep it as a different class */ - enum reg_class { - NO_REGS, LONG_REGS, GENERAL_REGS, SP_REG, SP_AND_G_REGS, - ALL_REGS, LIM_REG_CLASSES + NO_REGS, GENERAL_REGS, ALL_REGS, LIM_REG_CLASSES }; #define N_REG_CLASSES (int) LIM_REG_CLASSES @@ -332,8 +332,7 @@ enum reg_class { /* Give names of register classes as strings for dump file. */ #define REG_CLASS_NAMES \ -{ "NO_REGS", "LONG_REGS", "GENERAL_REGS", "SP_REG", "SP_AND_G_REGS", \ - "ALL_REGS", "LIM_REGS" } +{ "NO_REGS", "GENERAL_REGS", "ALL_REGS", "LIM_REGS" } /* Define which registers fit in which classes. This is an initializer for a vector of HARD_REG_SET @@ -341,22 +340,18 @@ enum reg_class { #define REG_CLASS_CONTENTS \ { 0, /* No regs */ \ - 0x07f, /* LONG_REGS */ \ - 0x07f, /* GENERAL_REGS */ \ - 0x080, /* SP_REG */ \ - 0x0ff, /* SP_AND_G_REGS */ \ + 0x0ff, /* GENERAL_REGS */ \ 0x1ff, /* ALL_REGS */ \ } /* The same information, inverted: Return the class number of the smallest class containing reg number REGNO. This could be a conditional expression - or could index an array. */ + or could index an array. -#define REGNO_REG_CLASS(REGNO) \ - ((REGNO) < 7 ? LONG_REGS : \ - (REGNO) == 7 ? SP_REG : \ - GENERAL_REGS) + ??? What about the ARG_POINTER_REGISTER? */ + +#define REGNO_REG_CLASS(REGNO) GENERAL_REGS /* The class value for index registers, and the one for base regs. */ @@ -365,8 +360,7 @@ enum reg_class { /* Get reg_class from a letter such as appears in the machine description. */ -#define REG_CLASS_FROM_LETTER(C) \ - ((C) == 'a' ? (SP_REG) : (C) == 'l' ? (LONG_REGS) : (NO_REGS)) +#define REG_CLASS_FROM_LETTER(C) (NO_REGS) /* The letters I, J, K, L, M, N, O, P in a register constraint string can be used to stand for particular ranges of immediate operands. @@ -1341,4 +1335,6 @@ do { char dstr[30]; \ /* Declarations for functions used in insn-output.c. */ char *emit_a_shift (); int h8300_funcvec_function_p (); -char *output_adds_subs(); +char *output_adds_subs (); +char * output_simode_bld (); + diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md index c177990..e7049dd 100644 --- a/gcc/config/h8300/h8300.md +++ b/gcc/config/h8300/h8300.md @@ -36,12 +36,6 @@ ;; * movXX insns using register indirect addressing. ;; * insns referencing the 8-bit area with an 8-bit address. -;; Some move patterns have conditions which check that one operand -;; is a register. Shouldn't all of them have such a condition? - -;; Consistently use "a" constraint. Probably makes little difference -;; in the generated code, but it's easy to do. - ;; Loading some 32bit integer constants could be done more ;; efficiently. For example loading the value 4 as a 32bit ;; is normally done via mov.l #4,erX. sub.l erX,erX, inc.l #4,erX @@ -63,6 +57,10 @@ ;; Long term, we want to expose the "e" half to the compiler (gives us ;; 8 more 16bit registers). At that point addhi and subhi can't use adds/subs. +;; There's currently no way to have a insv/extzv expander for the h8/300h +;; because word_mode is different for the h8/300 and h8/300h. + +;; ??? Implement remaining bit ops available on the h8300 (define_attr "type" "branch,bcs,arith" (const_string "arith")) @@ -191,7 +189,7 @@ ;; 16bit push insns! (define_insn "movhi_push" [(set (match_operand:HI 0 "push_operand" "=<") - (match_operand:HI 1 "register_operand" "ra"))] + (match_operand:HI 1 "register_operand" "r"))] "" "* { @@ -204,8 +202,8 @@ (set_attr "cc" "set")]) (define_insn "movhi_internal" - [(set (match_operand:HI 0 "general_operand_dst" "=ra,ra,<,ra,o") - (match_operand:HI 1 "general_operand_src" "I,ra>,ra,ion,ra"))] + [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,o") + (match_operand:HI 1 "general_operand_src" "I,r>,r,ion,r"))] "register_operand (operands[0],HImode) || register_operand (operands[1], HImode)" "@ @@ -418,8 +416,8 @@ (set_attr "cc" "clobber")]) (define_insn "movsi_h8300h" - [(set (match_operand:SI 0 "general_operand_dst" "=ra,ra,ra,o,<,ra") - (match_operand:SI 1 "general_operand_src" "I,ra,ion,ra,ra,>"))] + [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,o,<,r") + (match_operand:SI 1 "general_operand_src" "I,r,ion,r,r,>"))] "TARGET_H8300H && (register_operand (operands[0], SImode) || register_operand (operands[1], SImode))" @@ -487,21 +485,21 @@ (set_attr "cc" "set_zn_c0")]) (define_insn "tstqi" - [(set (cc0) (match_operand:QI 0 "general_operand" "ra"))] + [(set (cc0) (match_operand:QI 0 "general_operand" "r"))] "" "mov.b %X0,%X0" [(set_attr "length" "2") (set_attr "cc" "set")]) (define_insn "tsthi" - [(set (cc0) (match_operand:HI 0 "general_operand" "ra"))] + [(set (cc0) (match_operand:HI 0 "general_operand" "r"))] "" "mov.w %T0,%T0" [(set_attr "length" "2") (set_attr "cc" "set")]) (define_insn "tstsi" - [(set (cc0) (match_operand:SI 0 "general_operand" "ra"))] + [(set (cc0) (match_operand:SI 0 "general_operand" "r"))] "TARGET_H8300H" "mov.l %S0,%S0" [(set_attr "length" "2") @@ -509,8 +507,8 @@ (define_insn "cmpqi" [(set (cc0) - (compare:QI (match_operand:QI 0 "register_operand" "ra") - (match_operand:QI 1 "nonmemory_operand" "rai")))] + (compare:QI (match_operand:QI 0 "register_operand" "r") + (match_operand:QI 1 "nonmemory_operand" "ri")))] "" "cmp.b %X1,%X0" [(set_attr "length" "2") @@ -531,8 +529,8 @@ (define_insn "" [(set (cc0) - (compare:HI (match_operand:HI 0 "register_operand" "ra") - (match_operand:HI 1 "register_operand" "ra")))] + (compare:HI (match_operand:HI 0 "register_operand" "r") + (match_operand:HI 1 "register_operand" "r")))] "!TARGET_H8300H" "cmp.w %T1,%T0" [(set_attr "length" "2") @@ -540,8 +538,8 @@ (define_insn "" [(set (cc0) - (compare:HI (match_operand:HI 0 "register_operand" "ra") - (match_operand:HI 1 "nonmemory_operand" "rai")))] + (compare:HI (match_operand:HI 0 "register_operand" "r") + (match_operand:HI 1 "nonmemory_operand" "ri")))] "TARGET_H8300H" "cmp.w %T1,%T0" [(set_attr "length" "2") @@ -549,8 +547,8 @@ (define_insn "cmpsi" [(set (cc0) - (compare:SI (match_operand:SI 0 "register_operand" "ra") - (match_operand:SI 1 "nonmemory_operand" "rai")))] + (compare:SI (match_operand:SI 0 "register_operand" "r") + (match_operand:SI 1 "nonmemory_operand" "ri")))] "TARGET_H8300H" "cmp.l %S1,%S0" [(set_attr "length" "2") @@ -579,7 +577,7 @@ ;; Specialized version using adds/subs. This must come before ;; the more general patterns below. (define_insn "" - [(set (match_operand:HI 0 "register_operand" "=ra") + [(set (match_operand:HI 0 "register_operand" "=r") (plus:HI (match_operand:HI 1 "register_operand" "%0") (match_operand:HI 2 "adds_subs_operand" "i")))] "" @@ -588,20 +586,21 @@ (set_attr "cc" "none_0hit")]) (define_insn "" - [(set (match_operand:HI 0 "register_operand" "=&ra,ra") - (plus:HI (match_operand:HI 1 "register_operand" "%0,0") - (match_operand:HI 2 "nonmemory_operand" "n,ra")))] + [(set (match_operand:HI 0 "register_operand" "=&r,r,&r") + (plus:HI (match_operand:HI 1 "register_operand" "%0,0,g") + (match_operand:HI 2 "nonmemory_operand" "n,r,r")))] "TARGET_H8300" "@ add.b %s2,%s0\;addx %t2,%t0 - add.w %T2,%T0" - [(set_attr "length" "4,2") - (set_attr "cc" "clobber,set_zn_c0")]) + add.w %T2,%T0 + mov.w %T1,%T0\;add.w %T2,%T0" + [(set_attr "length" "4,2,6") + (set_attr "cc" "clobber,set_zn_c0,set_zn_c0")]) (define_insn "" - [(set (match_operand:HI 0 "register_operand" "=ra,ra") + [(set (match_operand:HI 0 "register_operand" "=r,r") (plus:HI (match_operand:HI 1 "register_operand" "%0,0") - (match_operand:HI 2 "nonmemory_operand" "i,ra")))] + (match_operand:HI 2 "nonmemory_operand" "i,r")))] "TARGET_H8300H" "@ add.w %T2,%T0 @@ -619,7 +618,7 @@ ;; Specialized version using adds/subs. This must come before ;; the more general patterns below. (define_insn "" - [(set (match_operand:SI 0 "register_operand" "=ra") + [(set (match_operand:SI 0 "register_operand" "=r") (plus:SI (match_operand:SI 1 "register_operand" "%0") (match_operand:SI 2 "adds_subs_operand" "i")))] "TARGET_H8300H" @@ -628,7 +627,7 @@ (set_attr "cc" "none_0hit")]) (define_insn "addsi_h8300" - [(set (match_operand:SI 0 "register_operand" "=ra,ra,&ra") + [(set (match_operand:SI 0 "register_operand" "=r,r,&r") (plus:SI (match_operand:SI 1 "register_operand" "%0,0,r") (match_operand:SI 2 "nonmemory_operand" "n,r,r")))] "TARGET_H8300" @@ -640,9 +639,9 @@ (set_attr "cc" "clobber")]) (define_insn "addsi_h8300h" - [(set (match_operand:SI 0 "register_operand" "=ra,ra") + [(set (match_operand:SI 0 "register_operand" "=r,r") (plus:SI (match_operand:SI 1 "register_operand" "%0,0") - (match_operand:SI 2 "nonmemory_operand" "i,ra")))] + (match_operand:SI 2 "nonmemory_operand" "i,r")))] "TARGET_H8300H" "@ add.l %S2,%S0 @@ -676,7 +675,7 @@ ;; the more general patterns below. This may not be needed ;; due to instruction canonicalization. (define_insn "" - [(set (match_operand:HI 0 "register_operand" "=ra") + [(set (match_operand:HI 0 "register_operand" "=r") (minus:HI (match_operand:HI 1 "register_operand" "r") (match_operand:HI 2 "adds_subs_operand" "i")))] "" @@ -689,9 +688,9 @@ (set_attr "cc" "none_0hit")]) (define_insn "" - [(set (match_operand:HI 0 "register_operand" "=ra,&ra") + [(set (match_operand:HI 0 "register_operand" "=r,&r") (minus:HI (match_operand:HI 1 "general_operand" "0,0") - (match_operand:HI 2 "nonmemory_operand" "ra,n")))] + (match_operand:HI 2 "nonmemory_operand" "r,n")))] "TARGET_H8300" "@ sub.w %T2,%T0 @@ -700,9 +699,9 @@ (set_attr "cc" "set_zn_c0,clobber")]) (define_insn "" - [(set (match_operand:HI 0 "register_operand" "=ra,&ra") + [(set (match_operand:HI 0 "register_operand" "=r,&r") (minus:HI (match_operand:HI 1 "general_operand" "0,0") - (match_operand:HI 2 "nonmemory_operand" "ra,i")))] + (match_operand:HI 2 "nonmemory_operand" "r,i")))] "TARGET_H8300H" "@ sub.w %T2,%T0 @@ -730,7 +729,7 @@ ;; the more general patterns below. This may not be needed ;; due to instruction canonicalization. (define_insn "" - [(set (match_operand:SI 0 "register_operand" "=ra") + [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (match_operand:SI 1 "general_operand" "0") (match_operand:SI 2 "adds_subs_operand" "i")))] "TARGET_H8300H" @@ -743,9 +742,9 @@ (set_attr "cc" "none_0hit")]) (define_insn "subsi3_h8300h" - [(set (match_operand:SI 0 "register_operand" "=ra,ra") + [(set (match_operand:SI 0 "register_operand" "=r,r") (minus:SI (match_operand:SI 1 "general_operand" "0,0") - (match_operand:SI 2 "nonmemory_operand" "ra,i")))] + (match_operand:SI 2 "nonmemory_operand" "r,i")))] "TARGET_H8300H" "@ sub.l %S2,%S0 @@ -1527,7 +1526,7 @@ (define_insn "zero_extendqihi2" [(set (match_operand:HI 0 "register_operand" "=r,r") - (zero_extend:HI (match_operand:QI 1 "general_operand" "0,g")))] + (zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))] "" "@ mov.b #0,%t0 @@ -1535,20 +1534,36 @@ [(set_attr "length" "2,4") (set_attr "cc" "clobber,clobber")]) +;; The compiler can synthesize a 300H variant of this which is +;; just as efficient as one that we'd create +(define_insn "zero_extendqisi2" + [(set (match_operand:SI 0 "register_operand" "=r,r") + (zero_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))] + "TARGET_H8300" + "@ + mov.b #0,%x0\;sub.w %e0,%e0 + mov.b %R1,%w0\;mov.b #0,%x0\;sub.w %e0,%e0" + [(set_attr "length" "4,6") + (set_attr "cc" "clobber,clobber")]) + (define_expand "zero_extendhisi2" [(set (match_operand:SI 0 "register_operand" "") (zero_extend:SI (match_operand:HI 1 "general_operand" "")))] "" " { + extern int optimize; + if (TARGET_H8300 - && GET_CODE (operands[1]) != CONST_INT) + && GET_CODE (operands[1]) != CONST_INT + && !optimize) { emit_insn (gen_zero_extendhisi2_h8300 (operands[0], operands[1])); DONE; } }") + ;; I don't know why, but if I try to simplify extendhisi2 in the ;; natural way, I get about a 2X code bloat on the h8300 without ;; optimization, and a small bloat with optimization. Weird. @@ -1561,7 +1576,7 @@ (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r,r") - (zero_extend:SI (match_operand:HI 1 "general_operand" "0,g")))] + (zero_extend:SI (match_operand:HI 1 "general_operand_src" "0,g>")))] "TARGET_H8300" "@ sub.w %e0,%e0 @@ -1571,7 +1586,7 @@ (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r,r") - (zero_extend:SI (match_operand:HI 1 "general_operand" "0,g")))] + (zero_extend:SI (match_operand:HI 1 "general_operand_src" "0,g>")))] "TARGET_H8300H" "@ extu.l %S0 @@ -1587,7 +1602,7 @@ (define_insn "" [(set (match_operand:HI 0 "register_operand" "=r,r") - (sign_extend:HI (match_operand:QI 1 "general_operand" "0,g")))] + (sign_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))] "TARGET_H8300" "@ bld #7,%s0\;subx %t0,%t0 @@ -1597,7 +1612,7 @@ (define_insn "" [(set (match_operand:HI 0 "register_operand" "=r,r") - (sign_extend:HI (match_operand:QI 1 "general_operand" "0,g")))] + (sign_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))] "TARGET_H8300H" "@ exts.w %T0 @@ -1605,14 +1620,28 @@ [(set_attr "length" "2,4") (set_attr "cc" "set,set")]) +;; The compiler can synthesize a 300H variant of this which is +;; just as efficient as one that we'd create +(define_insn "extendqisi2" + [(set (match_operand:SI 0 "register_operand" "=r,r") + (sign_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))] + "TARGET_H8300" + "@ + bld #7,%w0\;subx %x0,%x0\;subx %y0,%y0\;subx %z0,%z0 + mov.b %R1,%w0\;bld #7,%w0\;subx %x0,%x0\;subx %y0,%y0\;subx %z0,%z0" + [(set_attr "length" "8,10") + (set_attr "cc" "clobber,clobber")]) + (define_expand "extendhisi2" [(set (match_operand:SI 0 "register_operand" "") (sign_extend:SI (match_operand:HI 1 "general_operand" "")))] "" " { + extern int optimize; if (TARGET_H8300 - && GET_CODE (operands[1]) != CONST_INT) + && GET_CODE (operands[1]) != CONST_INT + && !optimize) { emit_insn (gen_extendhisi2_h8300 (operands[0], operands[1])); DONE; @@ -1631,7 +1660,7 @@ (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r,r") - (sign_extend:SI (match_operand:HI 1 "general_operand" "0,g")))] + (sign_extend:SI (match_operand:HI 1 "general_operand_src" "0,g>")))] "TARGET_H8300" "@ bld #7,%x0\;subx %y0,%y0\;subx %z0,%z0 @@ -1641,7 +1670,7 @@ (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r,r") - (sign_extend:SI (match_operand:HI 1 "general_operand" "0,g")))] + (sign_extend:SI (match_operand:HI 1 "general_operand_src" "0,g>")))] "TARGET_H8300H" "@ exts.l %S0 @@ -1719,7 +1748,7 @@ (define_expand "lshrhi3" [(set (match_operand:HI 0 "register_operand" "") - (lshiftrt:HI (match_operand:HI 1 "general_operand_src" "") + (lshiftrt:HI (match_operand:HI 1 "general_operand" "") (match_operand:QI 2 "nonmemory_operand" "")))] "" "if (expand_a_shift (HImode, LSHIFTRT, operands)) DONE;else FAIL;") @@ -1753,7 +1782,7 @@ (define_expand "ashlsi3" [(set (match_operand:SI 0 "register_operand" "") (ashift:SI - (match_operand:SI 1 "general_operand_src" "") + (match_operand:SI 1 "general_operand" "") (match_operand:QI 2 "nonmemory_operand" "")))] "" "if (expand_a_shift (SImode, ASHIFT, operands)) DONE;else FAIL;") @@ -1761,7 +1790,7 @@ (define_expand "lshrsi3" [(set (match_operand:SI 0 "register_operand" "") (lshiftrt:SI - (match_operand:SI 1 "general_operand_src" "") + (match_operand:SI 1 "general_operand" "") (match_operand:QI 2 "nonmemory_operand" "")))] "" "if (expand_a_shift (SImode, LSHIFTRT, operands)) DONE;else FAIL;") @@ -1769,7 +1798,7 @@ (define_expand "ashrsi3" [(set (match_operand:SI 0 "register_operand" "") (ashiftrt:SI - (match_operand:SI 1 "general_operand_src" "") + (match_operand:SI 1 "general_operand" "") (match_operand:QI 2 "nonmemory_operand" "")))] "" "if (expand_a_shift (SImode, ASHIFTRT, operands)) DONE;else FAIL;") @@ -1799,13 +1828,14 @@ ;; BCC and BCS patterns. -(define_insn "bcs_qiqi" +(define_insn "" [(set (pc) (if_then_else (match_operator 1 "eq_operator" - [(zero_extract:QI (match_operand:QI 2 "bit_operand" "Ur") - (const_int 1) - (match_operand:HI 3 "immediate_operand" "i")) + [(zero_extract:QI + (match_operand:HI 2 "register_operand" "r") + (const_int 1) + (match_operand:HI 3 "immediate_operand" "i")) (const_int 0)]) (label_ref (match_operand 0 "" "")) (pc)))] @@ -1817,7 +1847,7 @@ can easily choose the right branch length. */ int branch_length = get_attr_length (insn); - if (! register_operand (operands[2], QImode)) + if (! register_operand (operands[2], HImode)) branch_length -= 4; else branch_length -= 2; @@ -1833,13 +1863,14 @@ [(set_attr "type" "bcs") (set_attr "cc" "clobber")]) -(define_insn "bcs_hihi" +(define_insn "" [(set (pc) (if_then_else (match_operator 1 "eq_operator" - [(zero_extract:HI (match_operand:HI 2 "bit_operand" "Ur") - (const_int 1) - (match_operand:HI 3 "immediate_operand" "i")) + [(zero_extract:HI + (match_operand:HI 2 "register_operand" "r") + (const_int 1) + (match_operand:HI 3 "immediate_operand" "i")) (const_int 0)]) (label_ref (match_operand 0 "" "")) (pc)))] @@ -1851,7 +1882,7 @@ can easily choose the right branch length. */ int branch_length = get_attr_length (insn); - if (! register_operand (operands[2], QImode)) + if (! register_operand (operands[2], HImode)) branch_length -= 4; else branch_length -= 2; @@ -1867,16 +1898,17 @@ [(set_attr "type" "bcs") (set_attr "cc" "clobber")]) -(define_insn "bcs_hiqi" +(define_insn "" [(set (pc) (if_then_else (match_operator 1 "eq_operator" - [(zero_extract:HI (match_operand:QI 2 "bit_operand" "Ur") - (const_int 1) - (match_operand:HI 3 "immediate_operand" "i")) + [(zero_extract:HI + (match_operand:HI 2 "register_operand" "U") + (const_int 1) + (match_operand:HI 3 "immediate_operand" "i")) (const_int 0)]) - (label_ref (match_operand 0 "" "")) - (pc)))] + (pc) + (label_ref (match_operand 0 "" ""))))] "" "* { @@ -1885,7 +1917,7 @@ can easily choose the right branch length. */ int branch_length = get_attr_length (insn); - if (! register_operand (operands[2], QImode)) + if (! register_operand (operands[2], HImode)) branch_length -= 4; else branch_length -= 2; @@ -1901,11 +1933,56 @@ [(set_attr "type" "bcs") (set_attr "cc" "clobber")]) -;; BLD and BST patterns +(define_insn "" + [(set (pc) + (if_then_else + (match_operator 1 "eq_operator" + [(zero_extract:QI + (match_operand:HI 2 "register_operand" "r") + (const_int 1) + (match_operand:HI 3 "immediate_operand" "i")) + (const_int 0)]) + (pc) + (label_ref (match_operand 0 "" ""))))] + "" + "* +{ + /* The length of this insn includes the bld insn below. We + compute the length of the branch without the bld so we + can easily choose the right branch length. */ + int branch_length = get_attr_length (insn); + + if (! register_operand (operands[2], HImode)) + branch_length -= 4; + else + branch_length -= 2; -(define_insn "extract_1" + output_asm_insn(\"bld %Z3,%Y2\", operands); + if (branch_length == 2) + return \"%d1 %l0\"; + else if (branch_length == 4) + return \"%d1 %l0:16\"; + else + return \"%g1 %L0\;jmp @%l0\;%L0:\"; +}" + [(set_attr "type" "bcs") + (set_attr "cc" "clobber")]) + +;; You'll never believe all these patterns perform one basic action -- +;; load a bit from the source, optionally invert the bit, then store it +;; in the destination (which is known to be zero).. +;; +;; Combine obviously need some work to better identify this situation and +;; canonicalize the form better. + +;; +;; Normal loads with a 16bit destination. +;; +;; Yes, both cases are needed. +;; +(define_insn "" [(set (match_operand:HI 0 "register_operand" "=&r") - (zero_extract:HI (match_operand:QI 1 "bit_operand" "Ur") + (zero_extract:HI (match_operand:HI 1 "register_operand" "r") (const_int 1) (match_operand:HI 2 "immediate_operand" "i")))] "" @@ -1913,240 +1990,296 @@ [(set_attr "cc" "clobber") (set_attr "length" "6")]) -(define_insn "extract_1_hi" +(define_insn "" [(set (match_operand:HI 0 "register_operand" "=&r") - (zero_extract:HI (match_operand:HI 1 "bit_operand" "Ur") - (const_int 1) - (match_operand:HI 2 "immediate_operand" "i")))] + (subreg:HI (zero_extract:SI + (match_operand:HI 1 "register_operand" "r") + (const_int 1) + (match_operand:HI 2 "immediate_operand" "i")) 1))] "" "sub.w %0,%0\;bld %Z2,%Y1\;bst #0,%X0" [(set_attr "cc" "clobber") (set_attr "length" "6")]) -(define_insn "insert_1" - [(set (zero_extract:HI (match_operand:QI 0 "bit_operand" "+Ur") - (const_int 1) - (match_operand:HI 1 "immediate_operand" "i")) - (zero_extract:HI (match_operand:QI 2 "bit_operand" "Ur") +;; +;; Inverted loads with a 16bit destination. +;; +;; Yes, all four cases are needed. +;; + +(define_insn "" + [(set (match_operand:HI 0 "register_operand" "=&r") + (zero_extract:HI (xor:HI (match_operand:HI 1 "register_operand" "r") + (match_operand:HI 3 "p_operand" "P")) (const_int 1) - (const_int 0)))] + (match_operand:HI 2 "const_int_operand" "n")))] + "(1 << INTVAL (operands[2])) == INTVAL (operands[3])" + "sub.w %0,%0\;bild %Z2,%Y1\;bst #0,%X0" + [(set_attr "cc" "clobber") + (set_attr "length" "8")]) + +(define_insn "" + [(set (match_operand:HI 0 "register_operand" "=&r") + (and:HI (not:HI + (lshiftrt:HI + (match_operand:HI 1 "bit_operand" "Ur") + (match_operand:HI 2 "const_int_operand" "n"))) + (const_int 1)))] "" - "bld #0,%R2\;bst %Z1,%Y0 ; i1" + "sub.w %0,%0\;bild %Z2,%Y1\;bst #0,%X0" [(set_attr "cc" "clobber") - (set_attr "length" "4")]) + (set_attr "length" "8")]) -;; This is how combine canonicalizes this pattern. This is perhaps a bug -;; in combine.c, but there is no problem with writing it this way so we do. -(define_insn "extract_insert_1" - [(set (zero_extract:QI (match_operand:QI 0 "bit_operand" "+Ur") - (const_int 1) - (match_operand:HI 1 "immediate_operand" "i")) - (lshiftrt:QI (match_operand:QI 2 "bit_operand" "Ur") - (match_operand:HI 3 "immediate_operand" "i")))] - "" - "bld %Z3,%Y2\;bst %Z1,%Y0; ei1" +(define_insn "" + [(set (match_operand:HI 0 "register_operand" "=&r") + (and:HI (not:HI + (subreg:HI + (lshiftrt:SI + (match_operand:SI 1 "register_operand" "Ur") + (match_operand:SI 2 "const_int_operand" "n")) 1)) + (const_int 1)))] + "INTVAL (operands[2]) < 16" + "sub.w %0,%0\;bild %Z2,%Y1\;bst #0,%X0" [(set_attr "cc" "clobber") - (set_attr "length" "4")]) + (set_attr "length" "8")]) -;; BAND, BOR, and BXOR patterns +(define_insn "" + [(set (match_operand:HI 0 "register_operand" "=&r") + (and:HI (not:HI + (subreg:HI + (lshiftrt:SI + (match_operand:SI 1 "bit_operand" "Ur") + (match_operand:SI 2 "const_int_operand" "n")) 0)) + (const_int 1)))] + "TARGET_H8300H && INTVAL (operands[2]) < 16" + "sub.w %0,%0\;bild %Z2,%Y1\;bst #0,%X0" + [(set_attr "cc" "clobber") + (set_attr "length" "8")]) -(define_insn "bitlogical_1" - [(set (match_operand:HI 0 "bit_operand" "=Ur") - (match_operator:HI 4 "bit_operator" - [(zero_extract:HI (match_operand:QI 1 "bit_operand" "Ur") - (const_int 1) - (match_operand:HI 2 "immediate_operand" "i")) - (match_operand:HI 3 "bit_operand" "0")]))] +;; +;; Normal loads with a 32bit destination. +;; +;; Yes, all three cases are needed. +;; +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=&r") + (zero_extract:SI (match_operand:HI 1 "register_operand" "r") + (const_int 1) + (match_operand:HI 2 "const_int_operand" "n")))] "" - "bld %Z2,%Y1\;%b4 #0,%R0\;bst #0,%R0; bl1" + "* return output_simode_bld (0, 0, operands);" [(set_attr "cc" "clobber") - (set_attr "length" "6")]) + (set (attr "length") + (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0)) + (const_int 10) + (const_int 8)))]) -(define_insn "bitlogical_1_hi" - [(set (match_operand:HI 0 "bit_operand" "=Ur") - (match_operator:HI 4 "bit_operator" - [(zero_extract:HI (match_operand:HI 1 "bit_operand" "Ur") - (const_int 1) - (match_operand:HI 2 "immediate_operand" "i")) - (match_operand:HI 3 "bit_operand" "0")]))] - "" - "bld %Z2,%Y1\;%b4 #0,%R0\;bst #0,%R0; bl2" +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=&r") + (and:SI (zero_extend:SI + (lshiftrt:QI + (match_operand:QI 1 "bit_operand" "Ur") + (match_operand:QI 2 "const_int_operand" "n"))) + (const_int 1)))] + "" + "* return output_simode_bld (0, 0, operands);" [(set_attr "cc" "clobber") - (set_attr "length" "6")]) + (set (attr "length") + (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0)) + (const_int 10) + (const_int 8)))]) -(define_insn "bitlogical_2" - [(set (match_operand:HI 0 "bit_operand" "=Ur") - (match_operator:HI 5 "bit_operator" - [(zero_extract:HI (match_operand:QI 1 "bit_operand" "Ur") - (const_int 1) - (match_operand:HI 2 "immediate_operand" "i")) - (zero_extract:HI (match_operand:QI 3 "bit_operand" "Ur") - (const_int 1) - (match_operand:HI 4 "immediate_operand" "i"))]))] - "" - "bld %Z2,%Y1\;%b5 %Z4,%Y3\;bst #0,%R0; bl3" +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=&r") + (and:SI (zero_extend:SI + (lshiftrt:HI + (match_operand:HI 1 "bit_operand" "Ur") + (match_operand:HI 2 "const_int_operand" "n"))) + (const_int 1)))] + "" + "* return output_simode_bld (0, 0, operands);" [(set_attr "cc" "clobber") - (set_attr "length" "6")]) + (set (attr "length") + (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0)) + (const_int 10) + (const_int 8)))]) -(define_insn "bitlogical_2_hi" - [(set (match_operand:HI 0 "bit_operand" "=Ur") - (match_operator:HI 5 "bit_operator" - [(zero_extract:HI (match_operand:HI 1 "bit_operand" "Ur") - (const_int 1) - (match_operand:HI 2 "immediate_operand" "i")) - (zero_extract:HI (match_operand:HI 3 "bit_operand" "Ur") - (const_int 1) - (match_operand:HI 4 "immediate_operand" "i"))]))] +;; +;; Inverted loads with a 32bit destination. +;; +;; Yes, all seven cases are needed. +;; +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=&r") + (and:SI (not:SI + (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))) + (match_operand:SI 2 "p_operand" "P")))] "" - "bld %Z2,%Y1\;%b5 %Z4,%Y3\;bst #0,%R0; bl3" + "* return output_simode_bld (1, 1, operands);" [(set_attr "cc" "clobber") - (set_attr "length" "6")]) + (set (attr "length") + (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0)) + (const_int 10) + (const_int 8)))]) +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=&r") + (and:SI (not:SI + (zero_extend:SI + (lshiftrt:HI (match_operand:HI 1 "bit_operand" "Ur") + (match_operand:HI 2 "const_int_operand" "n")))) + (const_int 1)))] + "" + "* return output_simode_bld (1, 0, operands);" + [(set_attr "cc" "clobber") + (set (attr "length") + (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0)) + (const_int 10) + (const_int 8)))]) -;; This is how combine canonicalizes this pattern. This is perhaps a bug -;; in combine.c, but there is no problem with writing it this way so we do. -(define_insn "bitlogical_3" - [(set (zero_extract:QI (match_operand:QI 0 "bit_operand" "+Ur") - (const_int 1) - (match_operand:HI 1 "immediate_operand" "i")) - (match_operator:QI 6 "bit_operator" - [(lshiftrt:QI (match_operand:QI 2 "bit_operand" "Ur") - (match_operand:HI 3 "immediate_operand" "i")) - (lshiftrt:QI (match_operand:QI 4 "bit_operand" "Ur") - (match_operand:HI 5 "immediate_operand" "i"))]))] +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=&r") + (and:SI (not:SI + (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))) + (match_operand:SI 2 "p_operand" "P")))] "" - "bld %Z3,%Y2\;%b6 %Z5,%Y4\;bst %Z1,%Y0; bl5" + "* return output_simode_bld (1, 1, operands);" [(set_attr "cc" "clobber") - (set_attr "length" "6")]) - -;; This is how combine canonicalizes this pattern. This is perhaps a bug -;; in combine.c, but there is no problem with writing it this way so we do. -(define_insn "bitnot_1" - [(set (zero_extract:QI (match_operand:QI 0 "bit_operand" "=Ur") - (const_int 1) - (match_operand:HI 1 "immediate_operand" "i")) - (lshiftrt:QI (xor:QI (match_operand:QI 2 "bit_operand" "0") - (match_operand:HI 3 "immediate_operand" "i")) - (match_operand:HI 4 "immediate_operand" "1")))] - "GET_CODE (operands[3]) == CONST_INT && GET_CODE (operands[1]) == CONST_INT - && exact_log2 (INTVAL (operands[3])) == INTVAL (operands[1])" - "bnot %Z1,%Y0" - [(set_attr "cc" "none_0hit") - (set_attr "length" "2")]) + (set (attr "length") + (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0)) + (const_int 10) + (const_int 8)))]) +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=&r") + (and:SI (not:SI + (zero_extend:SI + (lshiftrt:QI (match_operand:QI 1 "bit_operand" "Ur") + (match_operand:QI 2 "const_int_operand" "n")))) + (const_int 1)))] + "" + "* return output_simode_bld (1, 0, operands);" + [(set_attr "cc" "clobber") + (set (attr "length") + (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0)) + (const_int 10) + (const_int 8)))]) -;; ??? Implement BIAND, BIOR, BIXOR +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=&r") + (and:SI (not:SI + (subreg:SI + (lshiftrt:HI + (match_operand:HI 1 "bit_operand" "Ur") + (match_operand:HI 2 "const_int_operand" "n")) 0)) + (const_int 1)))] + "1" + "* return output_simode_bld (1, 0, operands);" + [(set_attr "cc" "clobber") + (set (attr "length") + (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0)) + (const_int 10) + (const_int 8)))]) -;; ??? Implement BILD, BIST +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=&r") + (and:SI (not:SI + (subreg:SI + (lshiftrt:QI + (match_operand:QI 1 "bit_operand" "Ur") + (match_operand:QI 2 "const_int_operand" "n")) 0)) + (const_int 1)))] + "1" + "* return output_simode_bld (1, 0, operands);" + [(set_attr "cc" "clobber") + (set (attr "length") + (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0)) + (const_int 10) + (const_int 8)))]) -;; ??? Apparently general_operand for the 1st and 2nd operands is useful, -;; but I don't know why. --Jim +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=&r") + (zero_extract:SI (xor:HI (match_operand:HI 1 "register_operand" "r") + (match_operand:HI 3 "p_operand" "P")) + (const_int 1) + (match_operand:HI 2 "const_int_operand" "n")))] + "(1 << INTVAL (operands[2])) == INTVAL (operands[3])" + "sub.w %0,%0\;bild %Z2,%Y1\;bst #0,%X0" + [(set_attr "cc" "clobber") + (set_attr "length" "8")]) (define_expand "insv" - [(set (zero_extract:HI (match_operand:QI 0 "bit_operand" "Ur") - (match_operand:HI 1 "general_operand" "g") - (match_operand:HI 2 "general_operand" "g")) - (zero_extract:HI (match_operand:QI 3 "bit_operand" "Ur") - (const_int 1) - (const_int 0)))] -;; ??? This should have word mode which is SImode for the h8/300h. + [(set (zero_extract:HI (match_operand:HI 0 "general_operand" "") + (match_operand:HI 1 "general_operand" "") + (match_operand:HI 2 "general_operand" "")) + (match_operand:HI 3 "general_operand" ""))] "TARGET_H8300" " { + /* We only have single bit bitfield instructions. */ if (INTVAL (operands[1]) != 1) FAIL; - /* ??? HACK ??? - This INSV pattern is wrong. It should use HImode for operand 3. - Also, the zero_extract around operand 3 is superfluous and should be - deleted. Fixing this is more work than we care to do for the moment, - because it means most of the above patterns would need to be rewritten, - and we also need more combine.c patches to make this work. - - So, for now, we work around this bug by simply not accepting any bitfield - inserts that have a position greater than fits in QImode. */ - - if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) >= 8) + /* For now, we don't allow memory operands. */ + if (GET_CODE (operands[0]) == MEM + || GET_CODE (operands[3]) == MEM) FAIL; - - /* The bit_operand predicate accepts any memory during RTL generation, but - only 'U' memory afterwards, so if this is a MEM operand, we must force - it to be valid for 'U' by reloading the address. */ - - if (GET_CODE (operands[0]) == MEM && ! EXTRA_CONSTRAINT (operands[0], 'U')) - { - rtx mem; - mem = gen_rtx (MEM, GET_MODE (operands[0]), - copy_to_mode_reg (Pmode, XEXP (operands[0], 0))); - RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (operands[0]); - MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (operands[0]); - MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[0]); - operands[0] = mem; - } - - /* Likewise for operands[3]. */ - - if (GET_CODE (operands[3]) == MEM && ! EXTRA_CONSTRAINT (operands[3], 'U')) - { - rtx mem; - mem = gen_rtx (MEM, GET_MODE (operands[3]), - copy_to_mode_reg (Pmode, XEXP (operands[3], 0))); - RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (operands[3]); - MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (operands[3]); - MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[3]); - operands[3] = mem; - } }") -;; ??? Apparently general_operand for the 2nd and 3rd operands is useful, -;; but I don't know why. --Jim +(define_insn "" + [(set (zero_extract:HI (match_operand:HI 0 "register_operand" "+r") + (const_int 1) + (match_operand:HI 1 "immediate_operand" "i")) + (match_operand:HI 2 "register_operand" "r"))] + "" + "bld #0,%R2\;bst %Z1,%Y0 ; i1" + [(set_attr "cc" "clobber") + (set_attr "length" "4")]) (define_expand "extzv" [(set (match_operand:HI 0 "register_operand" "") - (zero_extract:HI (match_operand:QI 1 "bit_operand" "") - (match_operand:HI 2 "general_operand" "g") - (match_operand:HI 3 "general_operand" "g")))] -;; ??? This should have word mode which is SImode for the h8/300h. + (zero_extract:HI (match_operand:HI 1 "bit_operand" "") + (match_operand:HI 2 "general_operand" "") + (match_operand:HI 3 "general_operand" "")))] "TARGET_H8300" " { + /* We only have single bit bitfield instructions. */ if (INTVAL (operands[2]) != 1) FAIL; - /* The bit_operand predicate accepts any memory during RTL generation, but - only 'U' memory afterwards, so if this is a MEM operand, we must force - it to be valid for 'U' by reloading the address. */ - - if (GET_CODE (operands[1]) == MEM && ! EXTRA_CONSTRAINT (operands[1], 'U')) - { - rtx mem; - mem = gen_rtx (MEM, GET_MODE (operands[1]), - copy_to_mode_reg (Pmode, XEXP (operands[1], 0))); - RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (operands[1]); - MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (operands[1]); - MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[1]); - operands[1] = mem; - } + /* For now, we don't allow memory operands. */ + if (GET_CODE (operands[1]) == MEM) + FAIL; }") - -;; ----------------------------------------------------------------- -;; STACK POINTER MANIPULATIONS -;; ----------------------------------------------------------------- -;; This pattern is needed because there is no way on the H8/300 -;; to add a 16 bit immediate value to the stack pointer in one -;; instruction, which could leave an invalid instruction if interrupted -;; half way through. Here we add to the stack pointer from a -;; register. +;; BAND, BOR, and BXOR patterns -(define_insn "stack_pointer_manip" - [(set (match_operand:HI 0 "register_operand" "=&ra") - (plus:HI (match_operand:HI 1 "general_operand_src" "g") - (match_operand:HI 2 "register_operand" "ra")))] - "TARGET_H8300" - "mov.w %T1,%T0\;add.w %T2,%T0" - [(set_attr "length" "6") - (set_attr "cc" "set_zn_c0")]) +(define_insn "" + [(set (match_operand:HI 0 "bit_operand" "=Ur") + (match_operator:HI 4 "bit_operator" + [(zero_extract:HI (match_operand:HI 1 "register_operand" "r") + (const_int 1) + (match_operand:HI 2 "immediate_operand" "i")) + (match_operand:HI 3 "bit_operand" "0")]))] + "" + "bld %Z2,%Y1\;%b4 #0,%R0\;bst #0,%R0; bl1" + [(set_attr "cc" "clobber") + (set_attr "length" "6")]) +(define_insn "" + [(set (match_operand:HI 0 "bit_operand" "=Ur") + (match_operator:HI 5 "bit_operator" + [(zero_extract:HI (match_operand:HI 1 "register_operand" "r") + (const_int 1) + (match_operand:HI 2 "immediate_operand" "i")) + (zero_extract:HI (match_operand:HI 3 "register_operand" "r") + (const_int 1) + (match_operand:HI 4 "immediate_operand" "i"))]))] + "" + "bld %Z2,%Y1\;%b5 %Z4,%Y3\;bst #0,%R0; bl3" + [(set_attr "cc" "clobber") + (set_attr "length" "6")]) + ;; ------------------------------------------- ;; BLK moves ;; ------------------------------------------- @@ -2203,7 +2336,7 @@ (define_peephole [(set (match_operand:QI 0 "register_operand" "=r") - (mem:QI (plus:HI (match_operand:HI 1 "register_operand" "ra") + (mem:QI (plus:HI (match_operand:HI 1 "register_operand" "r") (match_operand:HI 2 "immediate_operand" "n")))) (set (match_operand:QI 3 "register_operand" "=r") (mem:QI (plus:HI (match_dup 1) @@ -2214,7 +2347,7 @@ (set_attr "cc" "set")]) (define_peephole - [(set (mem:QI (plus:HI (match_operand:HI 1 "register_operand" "ra") + [(set (mem:QI (plus:HI (match_operand:HI 1 "register_operand" "r") (match_operand:HI 2 "immediate_operand" "n"))) (match_operand:QI 0 "register_operand" "r")) (set (mem:QI (plus:HI (match_dup 1) @@ -2283,7 +2416,7 @@ (ior:QI (subreg:QI (ashift:HI (const_int 1) (match_operand:HI 1 "nonmemory_operand" "ri") ) 0) - (match_operand:QI 2 "general_operand" "Ur")))] + (match_operand:QI 2 "general_operand_src" "Ur>")))] "" "mov.b %R2,%R0\;bset %X1,%R0" [(set_attr "length" "4") @@ -2343,15 +2476,6 @@ [(set_attr "length" "2") (set_attr "cc" "clobber")]) -(define_insn "fancybclr" - [(set (match_operand:QI 0 "general_operand" "=r") - (and:QI (not:QI (match_operand:QI 1 "general_operand" "0")) - (match_operand:QI 2 "general_operand" "r")))] - "" - "not %X0\;and %X2,%X0" - [(set_attr "length" "4") - (set_attr "cc" "clobber")]) - (define_insn "fancybsetp3" [(set (match_operand:QI 0 "bit_operand" "=Ur") (ior:QI (subreg:QI (ashift:HI (const_int 1) @@ -2366,7 +2490,7 @@ [(set (match_operand:QI 0 "general_operand" "=r,U") (ior:QI (subreg:QI (ashift:HI (const_int 1) (match_operand:QI 1 "register_operand" "r,r")) 0) - (match_operand:QI 2 "general_operand" "U,r")))] + (match_operand:QI 2 "general_operand_src" "U,r>")))] "" "mov.b %R2,%R0\;bset %X1,%R0" [(set_attr "length" "4") @@ -2383,50 +2507,8 @@ [(set_attr "length" "2") (set_attr "cc" "clobber")]) -(define_insn "fancy_btst" - [(set (pc) - (if_then_else (eq (zero_extract:HI (zero_extend:HI (match_operand:QI 1 "general_operand" "Ur")) - (const_int 1) - (match_operand:HI 2 "nonmemory_operand" "rn")) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (get_attr_length (insn) == 2) - return \"btst %X2,%R1\;beq %l0\"; - else if (get_attr_length (insn) == 4) - return \"btst %X2,%R1\;beq %l0:16\"; - else - return \"btst %X2,%R1\;bne %L1\;jmp @%l0\;%L1:\"; -}" - [(set_attr "type" "branch") - (set_attr "cc" "clobber")]) - -(define_insn "fancy_btst1" - [(set (pc) - (if_then_else (ne (zero_extract:HI (zero_extend:HI (match_operand:QI 1 "general_operand" "Ur")) - (const_int 1) - (match_operand:HI 2 "nonmemory_operand" "rn")) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (get_attr_length (insn) == 2) - return \"btst %X2,%R1\;bne %l0\"; - else if (get_attr_length (insn) == 4) - return \"btst %X2,%R1\;bne %l0:16\"; - else - return \"btst %X2,%R1\;beq %L1\;jmp @%l0\;%L1:\"; -}" - [(set_attr "type" "branch") - (set_attr "cc" "clobber")]) - (define_insn "pxor" - [(set (zero_extract:QI (match_operand:QI 0 "bit_operand" "=r,U") + [(set (zero_extract:QI (match_operand:HI 0 "register_operand" "=r,r") (const_int 1) (match_operand 1 "immediate_operand" "n,n")) (and:QI (not:QI (match_operand:QI 2 "bit_operand" "r,U")) @@ -2435,3 +2517,31 @@ "bld #0,%R2\;bist %1,%0" [(set_attr "length" "4") (set_attr "cc" "clobber")]) + +(define_insn "" + [(set (match_operand:QI 0 "register_operand" "=r") + (and:QI (not:QI (match_operand:QI 1 "register_operand" "0")) + (match_operand:QI 2 "nonmemory_operand" "rJ")))] + "" + "not.b %X0\;and.b %X2,%X0" + [(set_attr "length" "4") + (set_attr "cc" "clobber")]) + +(define_insn "" + [(set (match_operand:HI 0 "register_operand" "=r") + (and:HI (not:HI (match_operand:HI 1 "register_operand" "0")) + (match_operand:HI 2 "nonmemory_operand" "rJ")))] + "TARGET_H8300H" + "not.w %T0\;and.w %T2,%T0" + [(set_attr "length" "4") + (set_attr "cc" "clobber")]) + +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") + (and:SI (not:SI (match_operand:SI 1 "register_operand" "0")) + (match_operand:QI 2 "nonmemory_operand" "rJ")))] + "TARGET_H8300H" + "not.l %S0\;and.l %S2,%S0" + [(set_attr "length" "4") + (set_attr "cc" "clobber")]) + |