Commit bd93f126 by Jeff Law

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
parent 2ac42d3a
...@@ -104,7 +104,7 @@ byte_reg (x, b) ...@@ -104,7 +104,7 @@ byte_reg (x, b)
{ {
static char *names_small[] = static char *names_small[] =
{"r0l", "r0h", "r1l", "r1h", "r2l", "r2h", "r3l", "r3h", {"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]; return names_small[REGNO (x) * 2 + b];
} }
...@@ -1545,8 +1545,6 @@ expand_a_shift (mode, code, operands) ...@@ -1545,8 +1545,6 @@ expand_a_shift (mode, code, operands)
int code; int code;
rtx operands[]; rtx operands[];
{ {
extern int rtx_equal_function_value_matters;
emit_move_insn (operands[0], operands[1]); emit_move_insn (operands[0], operands[1]);
/* need a loop to get all the bits we want - we generate the /* 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) ...@@ -2229,3 +2227,29 @@ h8300_valid_machine_decl_attribute (decl, attributes, attr, args)
return 0; 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 "";
}
...@@ -125,8 +125,12 @@ do { \ ...@@ -125,8 +125,12 @@ do { \
/* Define this if addresses of constant functions /* Define this if addresses of constant functions
shouldn't be put through pseudo regs where they can be cse'd. shouldn't be put through pseudo regs where they can be cse'd.
Desirable on machines where ordinary constants are expensive Desirable on machines where ordinary constants are expensive
but a CALL with constant address is cheap. */ but a CALL with constant address is cheap.
/* #define NO_FUNCTION_CSE */
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 */ /* Target machine storage layout */
...@@ -319,12 +323,8 @@ do { \ ...@@ -319,12 +323,8 @@ do { \
For any two classes, it is very desirable that there be another For any two classes, it is very desirable that there be another
class that represents their union. */ 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 { enum reg_class {
NO_REGS, LONG_REGS, GENERAL_REGS, SP_REG, SP_AND_G_REGS, NO_REGS, GENERAL_REGS, ALL_REGS, LIM_REG_CLASSES
ALL_REGS, LIM_REG_CLASSES
}; };
#define N_REG_CLASSES (int) LIM_REG_CLASSES #define N_REG_CLASSES (int) LIM_REG_CLASSES
...@@ -332,8 +332,7 @@ enum reg_class { ...@@ -332,8 +332,7 @@ enum reg_class {
/* Give names of register classes as strings for dump file. */ /* Give names of register classes as strings for dump file. */
#define REG_CLASS_NAMES \ #define REG_CLASS_NAMES \
{ "NO_REGS", "LONG_REGS", "GENERAL_REGS", "SP_REG", "SP_AND_G_REGS", \ { "NO_REGS", "GENERAL_REGS", "ALL_REGS", "LIM_REGS" }
"ALL_REGS", "LIM_REGS" }
/* Define which registers fit in which classes. /* Define which registers fit in which classes.
This is an initializer for a vector of HARD_REG_SET This is an initializer for a vector of HARD_REG_SET
...@@ -341,22 +340,18 @@ enum reg_class { ...@@ -341,22 +340,18 @@ enum reg_class {
#define REG_CLASS_CONTENTS \ #define REG_CLASS_CONTENTS \
{ 0, /* No regs */ \ { 0, /* No regs */ \
0x07f, /* LONG_REGS */ \ 0x0ff, /* GENERAL_REGS */ \
0x07f, /* GENERAL_REGS */ \
0x080, /* SP_REG */ \
0x0ff, /* SP_AND_G_REGS */ \
0x1ff, /* ALL_REGS */ \ 0x1ff, /* ALL_REGS */ \
} }
/* The same information, inverted: /* The same information, inverted:
Return the class number of the smallest class containing Return the class number of the smallest class containing
reg number REGNO. This could be a conditional expression reg number REGNO. This could be a conditional expression
or could index an array. */ or could index an array.
#define REGNO_REG_CLASS(REGNO) \ ??? What about the ARG_POINTER_REGISTER? */
((REGNO) < 7 ? LONG_REGS : \
(REGNO) == 7 ? SP_REG : \ #define REGNO_REG_CLASS(REGNO) GENERAL_REGS
GENERAL_REGS)
/* The class value for index registers, and the one for base regs. */ /* The class value for index registers, and the one for base regs. */
...@@ -365,8 +360,7 @@ enum reg_class { ...@@ -365,8 +360,7 @@ enum reg_class {
/* Get reg_class from a letter such as appears in the machine description. */ /* Get reg_class from a letter such as appears in the machine description. */
#define REG_CLASS_FROM_LETTER(C) \ #define REG_CLASS_FROM_LETTER(C) (NO_REGS)
((C) == 'a' ? (SP_REG) : (C) == 'l' ? (LONG_REGS) : (NO_REGS))
/* The letters I, J, K, L, M, N, O, P in a register constraint string /* 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. can be used to stand for particular ranges of immediate operands.
...@@ -1341,4 +1335,6 @@ do { char dstr[30]; \ ...@@ -1341,4 +1335,6 @@ do { char dstr[30]; \
/* Declarations for functions used in insn-output.c. */ /* Declarations for functions used in insn-output.c. */
char *emit_a_shift (); char *emit_a_shift ();
int h8300_funcvec_function_p (); int h8300_funcvec_function_p ();
char *output_adds_subs(); char *output_adds_subs ();
char * output_simode_bld ();
...@@ -36,12 +36,6 @@ ...@@ -36,12 +36,6 @@
;; * movXX insns using register indirect addressing. ;; * movXX insns using register indirect addressing.
;; * insns referencing the 8-bit area with an 8-bit address. ;; * 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 ;; Loading some 32bit integer constants could be done more
;; efficiently. For example loading the value 4 as a 32bit ;; 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 ;; is normally done via mov.l #4,erX. sub.l erX,erX, inc.l #4,erX
...@@ -63,6 +57,10 @@ ...@@ -63,6 +57,10 @@
;; Long term, we want to expose the "e" half to the compiler (gives us ;; 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. ;; 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" (define_attr "type" "branch,bcs,arith"
(const_string "arith")) (const_string "arith"))
...@@ -191,7 +189,7 @@ ...@@ -191,7 +189,7 @@
;; 16bit push insns! ;; 16bit push insns!
(define_insn "movhi_push" (define_insn "movhi_push"
[(set (match_operand:HI 0 "push_operand" "=<") [(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 @@ ...@@ -204,8 +202,8 @@
(set_attr "cc" "set")]) (set_attr "cc" "set")])
(define_insn "movhi_internal" (define_insn "movhi_internal"
[(set (match_operand:HI 0 "general_operand_dst" "=ra,ra,<,ra,o") [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,o")
(match_operand:HI 1 "general_operand_src" "I,ra>,ra,ion,ra"))] (match_operand:HI 1 "general_operand_src" "I,r>,r,ion,r"))]
"register_operand (operands[0],HImode) "register_operand (operands[0],HImode)
|| register_operand (operands[1], HImode)" || register_operand (operands[1], HImode)"
"@ "@
...@@ -418,8 +416,8 @@ ...@@ -418,8 +416,8 @@
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
(define_insn "movsi_h8300h" (define_insn "movsi_h8300h"
[(set (match_operand:SI 0 "general_operand_dst" "=ra,ra,ra,o,<,ra") [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,o,<,r")
(match_operand:SI 1 "general_operand_src" "I,ra,ion,ra,ra,>"))] (match_operand:SI 1 "general_operand_src" "I,r,ion,r,r,>"))]
"TARGET_H8300H "TARGET_H8300H
&& (register_operand (operands[0], SImode) && (register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode))" || register_operand (operands[1], SImode))"
...@@ -487,21 +485,21 @@ ...@@ -487,21 +485,21 @@
(set_attr "cc" "set_zn_c0")]) (set_attr "cc" "set_zn_c0")])
(define_insn "tstqi" (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" "mov.b %X0,%X0"
[(set_attr "length" "2") [(set_attr "length" "2")
(set_attr "cc" "set")]) (set_attr "cc" "set")])
(define_insn "tsthi" (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" "mov.w %T0,%T0"
[(set_attr "length" "2") [(set_attr "length" "2")
(set_attr "cc" "set")]) (set_attr "cc" "set")])
(define_insn "tstsi" (define_insn "tstsi"
[(set (cc0) (match_operand:SI 0 "general_operand" "ra"))] [(set (cc0) (match_operand:SI 0 "general_operand" "r"))]
"TARGET_H8300H" "TARGET_H8300H"
"mov.l %S0,%S0" "mov.l %S0,%S0"
[(set_attr "length" "2") [(set_attr "length" "2")
...@@ -509,8 +507,8 @@ ...@@ -509,8 +507,8 @@
(define_insn "cmpqi" (define_insn "cmpqi"
[(set (cc0) [(set (cc0)
(compare:QI (match_operand:QI 0 "register_operand" "ra") (compare:QI (match_operand:QI 0 "register_operand" "r")
(match_operand:QI 1 "nonmemory_operand" "rai")))] (match_operand:QI 1 "nonmemory_operand" "ri")))]
"" ""
"cmp.b %X1,%X0" "cmp.b %X1,%X0"
[(set_attr "length" "2") [(set_attr "length" "2")
...@@ -531,8 +529,8 @@ ...@@ -531,8 +529,8 @@
(define_insn "" (define_insn ""
[(set (cc0) [(set (cc0)
(compare:HI (match_operand:HI 0 "register_operand" "ra") (compare:HI (match_operand:HI 0 "register_operand" "r")
(match_operand:HI 1 "register_operand" "ra")))] (match_operand:HI 1 "register_operand" "r")))]
"!TARGET_H8300H" "!TARGET_H8300H"
"cmp.w %T1,%T0" "cmp.w %T1,%T0"
[(set_attr "length" "2") [(set_attr "length" "2")
...@@ -540,8 +538,8 @@ ...@@ -540,8 +538,8 @@
(define_insn "" (define_insn ""
[(set (cc0) [(set (cc0)
(compare:HI (match_operand:HI 0 "register_operand" "ra") (compare:HI (match_operand:HI 0 "register_operand" "r")
(match_operand:HI 1 "nonmemory_operand" "rai")))] (match_operand:HI 1 "nonmemory_operand" "ri")))]
"TARGET_H8300H" "TARGET_H8300H"
"cmp.w %T1,%T0" "cmp.w %T1,%T0"
[(set_attr "length" "2") [(set_attr "length" "2")
...@@ -549,8 +547,8 @@ ...@@ -549,8 +547,8 @@
(define_insn "cmpsi" (define_insn "cmpsi"
[(set (cc0) [(set (cc0)
(compare:SI (match_operand:SI 0 "register_operand" "ra") (compare:SI (match_operand:SI 0 "register_operand" "r")
(match_operand:SI 1 "nonmemory_operand" "rai")))] (match_operand:SI 1 "nonmemory_operand" "ri")))]
"TARGET_H8300H" "TARGET_H8300H"
"cmp.l %S1,%S0" "cmp.l %S1,%S0"
[(set_attr "length" "2") [(set_attr "length" "2")
...@@ -579,7 +577,7 @@ ...@@ -579,7 +577,7 @@
;; Specialized version using adds/subs. This must come before ;; Specialized version using adds/subs. This must come before
;; the more general patterns below. ;; the more general patterns below.
(define_insn "" (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") (plus:HI (match_operand:HI 1 "register_operand" "%0")
(match_operand:HI 2 "adds_subs_operand" "i")))] (match_operand:HI 2 "adds_subs_operand" "i")))]
"" ""
...@@ -588,20 +586,21 @@ ...@@ -588,20 +586,21 @@
(set_attr "cc" "none_0hit")]) (set_attr "cc" "none_0hit")])
(define_insn "" (define_insn ""
[(set (match_operand:HI 0 "register_operand" "=&ra,ra") [(set (match_operand:HI 0 "register_operand" "=&r,r,&r")
(plus:HI (match_operand:HI 1 "register_operand" "%0,0") (plus:HI (match_operand:HI 1 "register_operand" "%0,0,g")
(match_operand:HI 2 "nonmemory_operand" "n,ra")))] (match_operand:HI 2 "nonmemory_operand" "n,r,r")))]
"TARGET_H8300" "TARGET_H8300"
"@ "@
add.b %s2,%s0\;addx %t2,%t0 add.b %s2,%s0\;addx %t2,%t0
add.w %T2,%T0" add.w %T2,%T0
[(set_attr "length" "4,2") mov.w %T1,%T0\;add.w %T2,%T0"
(set_attr "cc" "clobber,set_zn_c0")]) [(set_attr "length" "4,2,6")
(set_attr "cc" "clobber,set_zn_c0,set_zn_c0")])
(define_insn "" (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") (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" "TARGET_H8300H"
"@ "@
add.w %T2,%T0 add.w %T2,%T0
...@@ -619,7 +618,7 @@ ...@@ -619,7 +618,7 @@
;; Specialized version using adds/subs. This must come before ;; Specialized version using adds/subs. This must come before
;; the more general patterns below. ;; the more general patterns below.
(define_insn "" (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") (plus:SI (match_operand:SI 1 "register_operand" "%0")
(match_operand:SI 2 "adds_subs_operand" "i")))] (match_operand:SI 2 "adds_subs_operand" "i")))]
"TARGET_H8300H" "TARGET_H8300H"
...@@ -628,7 +627,7 @@ ...@@ -628,7 +627,7 @@
(set_attr "cc" "none_0hit")]) (set_attr "cc" "none_0hit")])
(define_insn "addsi_h8300" (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") (plus:SI (match_operand:SI 1 "register_operand" "%0,0,r")
(match_operand:SI 2 "nonmemory_operand" "n,r,r")))] (match_operand:SI 2 "nonmemory_operand" "n,r,r")))]
"TARGET_H8300" "TARGET_H8300"
...@@ -640,9 +639,9 @@ ...@@ -640,9 +639,9 @@
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
(define_insn "addsi_h8300h" (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") (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" "TARGET_H8300H"
"@ "@
add.l %S2,%S0 add.l %S2,%S0
...@@ -676,7 +675,7 @@ ...@@ -676,7 +675,7 @@
;; the more general patterns below. This may not be needed ;; the more general patterns below. This may not be needed
;; due to instruction canonicalization. ;; due to instruction canonicalization.
(define_insn "" (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") (minus:HI (match_operand:HI 1 "register_operand" "r")
(match_operand:HI 2 "adds_subs_operand" "i")))] (match_operand:HI 2 "adds_subs_operand" "i")))]
"" ""
...@@ -689,9 +688,9 @@ ...@@ -689,9 +688,9 @@
(set_attr "cc" "none_0hit")]) (set_attr "cc" "none_0hit")])
(define_insn "" (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") (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" "TARGET_H8300"
"@ "@
sub.w %T2,%T0 sub.w %T2,%T0
...@@ -700,9 +699,9 @@ ...@@ -700,9 +699,9 @@
(set_attr "cc" "set_zn_c0,clobber")]) (set_attr "cc" "set_zn_c0,clobber")])
(define_insn "" (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") (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" "TARGET_H8300H"
"@ "@
sub.w %T2,%T0 sub.w %T2,%T0
...@@ -730,7 +729,7 @@ ...@@ -730,7 +729,7 @@
;; the more general patterns below. This may not be needed ;; the more general patterns below. This may not be needed
;; due to instruction canonicalization. ;; due to instruction canonicalization.
(define_insn "" (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") (minus:SI (match_operand:SI 1 "general_operand" "0")
(match_operand:SI 2 "adds_subs_operand" "i")))] (match_operand:SI 2 "adds_subs_operand" "i")))]
"TARGET_H8300H" "TARGET_H8300H"
...@@ -743,9 +742,9 @@ ...@@ -743,9 +742,9 @@
(set_attr "cc" "none_0hit")]) (set_attr "cc" "none_0hit")])
(define_insn "subsi3_h8300h" (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") (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" "TARGET_H8300H"
"@ "@
sub.l %S2,%S0 sub.l %S2,%S0
...@@ -1527,7 +1526,7 @@ ...@@ -1527,7 +1526,7 @@
(define_insn "zero_extendqihi2" (define_insn "zero_extendqihi2"
[(set (match_operand:HI 0 "register_operand" "=r,r") [(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 mov.b #0,%t0
...@@ -1535,20 +1534,36 @@ ...@@ -1535,20 +1534,36 @@
[(set_attr "length" "2,4") [(set_attr "length" "2,4")
(set_attr "cc" "clobber,clobber")]) (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" (define_expand "zero_extendhisi2"
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand:SI 0 "register_operand" "")
(zero_extend:SI (match_operand:HI 1 "general_operand" "")))] (zero_extend:SI (match_operand:HI 1 "general_operand" "")))]
"" ""
" "
{ {
extern int optimize;
if (TARGET_H8300 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])); emit_insn (gen_zero_extendhisi2_h8300 (operands[0], operands[1]));
DONE; DONE;
} }
}") }")
;; I don't know why, but if I try to simplify extendhisi2 in the ;; 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 ;; natural way, I get about a 2X code bloat on the h8300 without
;; optimization, and a small bloat with optimization. Weird. ;; optimization, and a small bloat with optimization. Weird.
...@@ -1561,7 +1576,7 @@ ...@@ -1561,7 +1576,7 @@
(define_insn "" (define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r") [(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" "TARGET_H8300"
"@ "@
sub.w %e0,%e0 sub.w %e0,%e0
...@@ -1571,7 +1586,7 @@ ...@@ -1571,7 +1586,7 @@
(define_insn "" (define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r") [(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" "TARGET_H8300H"
"@ "@
extu.l %S0 extu.l %S0
...@@ -1587,7 +1602,7 @@ ...@@ -1587,7 +1602,7 @@
(define_insn "" (define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r") [(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" "TARGET_H8300"
"@ "@
bld #7,%s0\;subx %t0,%t0 bld #7,%s0\;subx %t0,%t0
...@@ -1597,7 +1612,7 @@ ...@@ -1597,7 +1612,7 @@
(define_insn "" (define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r") [(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" "TARGET_H8300H"
"@ "@
exts.w %T0 exts.w %T0
...@@ -1605,14 +1620,28 @@ ...@@ -1605,14 +1620,28 @@
[(set_attr "length" "2,4") [(set_attr "length" "2,4")
(set_attr "cc" "set,set")]) (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" (define_expand "extendhisi2"
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand:SI 0 "register_operand" "")
(sign_extend:SI (match_operand:HI 1 "general_operand" "")))] (sign_extend:SI (match_operand:HI 1 "general_operand" "")))]
"" ""
" "
{ {
extern int optimize;
if (TARGET_H8300 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])); emit_insn (gen_extendhisi2_h8300 (operands[0], operands[1]));
DONE; DONE;
...@@ -1631,7 +1660,7 @@ ...@@ -1631,7 +1660,7 @@
(define_insn "" (define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r") [(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" "TARGET_H8300"
"@ "@
bld #7,%x0\;subx %y0,%y0\;subx %z0,%z0 bld #7,%x0\;subx %y0,%y0\;subx %z0,%z0
...@@ -1641,7 +1670,7 @@ ...@@ -1641,7 +1670,7 @@
(define_insn "" (define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r") [(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" "TARGET_H8300H"
"@ "@
exts.l %S0 exts.l %S0
...@@ -1719,7 +1748,7 @@ ...@@ -1719,7 +1748,7 @@
(define_expand "lshrhi3" (define_expand "lshrhi3"
[(set (match_operand:HI 0 "register_operand" "") [(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" "")))] (match_operand:QI 2 "nonmemory_operand" "")))]
"" ""
"if (expand_a_shift (HImode, LSHIFTRT, operands)) DONE;else FAIL;") "if (expand_a_shift (HImode, LSHIFTRT, operands)) DONE;else FAIL;")
...@@ -1753,7 +1782,7 @@ ...@@ -1753,7 +1782,7 @@
(define_expand "ashlsi3" (define_expand "ashlsi3"
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand:SI 0 "register_operand" "")
(ashift:SI (ashift:SI
(match_operand:SI 1 "general_operand_src" "") (match_operand:SI 1 "general_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))] (match_operand:QI 2 "nonmemory_operand" "")))]
"" ""
"if (expand_a_shift (SImode, ASHIFT, operands)) DONE;else FAIL;") "if (expand_a_shift (SImode, ASHIFT, operands)) DONE;else FAIL;")
...@@ -1761,7 +1790,7 @@ ...@@ -1761,7 +1790,7 @@
(define_expand "lshrsi3" (define_expand "lshrsi3"
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand:SI 0 "register_operand" "")
(lshiftrt:SI (lshiftrt:SI
(match_operand:SI 1 "general_operand_src" "") (match_operand:SI 1 "general_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))] (match_operand:QI 2 "nonmemory_operand" "")))]
"" ""
"if (expand_a_shift (SImode, LSHIFTRT, operands)) DONE;else FAIL;") "if (expand_a_shift (SImode, LSHIFTRT, operands)) DONE;else FAIL;")
...@@ -1769,7 +1798,7 @@ ...@@ -1769,7 +1798,7 @@
(define_expand "ashrsi3" (define_expand "ashrsi3"
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand:SI 0 "register_operand" "")
(ashiftrt:SI (ashiftrt:SI
(match_operand:SI 1 "general_operand_src" "") (match_operand:SI 1 "general_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))] (match_operand:QI 2 "nonmemory_operand" "")))]
"" ""
"if (expand_a_shift (SImode, ASHIFTRT, operands)) DONE;else FAIL;") "if (expand_a_shift (SImode, ASHIFTRT, operands)) DONE;else FAIL;")
...@@ -1799,13 +1828,14 @@ ...@@ -1799,13 +1828,14 @@
;; BCC and BCS patterns. ;; BCC and BCS patterns.
(define_insn "bcs_qiqi" (define_insn ""
[(set (pc) [(set (pc)
(if_then_else (if_then_else
(match_operator 1 "eq_operator" (match_operator 1 "eq_operator"
[(zero_extract:QI (match_operand:QI 2 "bit_operand" "Ur") [(zero_extract:QI
(const_int 1) (match_operand:HI 2 "register_operand" "r")
(match_operand:HI 3 "immediate_operand" "i")) (const_int 1)
(match_operand:HI 3 "immediate_operand" "i"))
(const_int 0)]) (const_int 0)])
(label_ref (match_operand 0 "" "")) (label_ref (match_operand 0 "" ""))
(pc)))] (pc)))]
...@@ -1817,7 +1847,7 @@ ...@@ -1817,7 +1847,7 @@
can easily choose the right branch length. */ can easily choose the right branch length. */
int branch_length = get_attr_length (insn); int branch_length = get_attr_length (insn);
if (! register_operand (operands[2], QImode)) if (! register_operand (operands[2], HImode))
branch_length -= 4; branch_length -= 4;
else else
branch_length -= 2; branch_length -= 2;
...@@ -1833,13 +1863,14 @@ ...@@ -1833,13 +1863,14 @@
[(set_attr "type" "bcs") [(set_attr "type" "bcs")
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
(define_insn "bcs_hihi" (define_insn ""
[(set (pc) [(set (pc)
(if_then_else (if_then_else
(match_operator 1 "eq_operator" (match_operator 1 "eq_operator"
[(zero_extract:HI (match_operand:HI 2 "bit_operand" "Ur") [(zero_extract:HI
(const_int 1) (match_operand:HI 2 "register_operand" "r")
(match_operand:HI 3 "immediate_operand" "i")) (const_int 1)
(match_operand:HI 3 "immediate_operand" "i"))
(const_int 0)]) (const_int 0)])
(label_ref (match_operand 0 "" "")) (label_ref (match_operand 0 "" ""))
(pc)))] (pc)))]
...@@ -1851,7 +1882,7 @@ ...@@ -1851,7 +1882,7 @@
can easily choose the right branch length. */ can easily choose the right branch length. */
int branch_length = get_attr_length (insn); int branch_length = get_attr_length (insn);
if (! register_operand (operands[2], QImode)) if (! register_operand (operands[2], HImode))
branch_length -= 4; branch_length -= 4;
else else
branch_length -= 2; branch_length -= 2;
...@@ -1867,16 +1898,17 @@ ...@@ -1867,16 +1898,17 @@
[(set_attr "type" "bcs") [(set_attr "type" "bcs")
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
(define_insn "bcs_hiqi" (define_insn ""
[(set (pc) [(set (pc)
(if_then_else (if_then_else
(match_operator 1 "eq_operator" (match_operator 1 "eq_operator"
[(zero_extract:HI (match_operand:QI 2 "bit_operand" "Ur") [(zero_extract:HI
(const_int 1) (match_operand:HI 2 "register_operand" "U")
(match_operand:HI 3 "immediate_operand" "i")) (const_int 1)
(match_operand:HI 3 "immediate_operand" "i"))
(const_int 0)]) (const_int 0)])
(label_ref (match_operand 0 "" "")) (pc)
(pc)))] (label_ref (match_operand 0 "" ""))))]
"" ""
"* "*
{ {
...@@ -1885,7 +1917,7 @@ ...@@ -1885,7 +1917,7 @@
can easily choose the right branch length. */ can easily choose the right branch length. */
int branch_length = get_attr_length (insn); int branch_length = get_attr_length (insn);
if (! register_operand (operands[2], QImode)) if (! register_operand (operands[2], HImode))
branch_length -= 4; branch_length -= 4;
else else
branch_length -= 2; branch_length -= 2;
...@@ -1901,11 +1933,56 @@ ...@@ -1901,11 +1933,56 @@
[(set_attr "type" "bcs") [(set_attr "type" "bcs")
(set_attr "cc" "clobber")]) (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") [(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) (const_int 1)
(match_operand:HI 2 "immediate_operand" "i")))] (match_operand:HI 2 "immediate_operand" "i")))]
"" ""
...@@ -1913,240 +1990,296 @@ ...@@ -1913,240 +1990,296 @@
[(set_attr "cc" "clobber") [(set_attr "cc" "clobber")
(set_attr "length" "6")]) (set_attr "length" "6")])
(define_insn "extract_1_hi" (define_insn ""
[(set (match_operand:HI 0 "register_operand" "=&r") [(set (match_operand:HI 0 "register_operand" "=&r")
(zero_extract:HI (match_operand:HI 1 "bit_operand" "Ur") (subreg:HI (zero_extract:SI
(const_int 1) (match_operand:HI 1 "register_operand" "r")
(match_operand:HI 2 "immediate_operand" "i")))] (const_int 1)
(match_operand:HI 2 "immediate_operand" "i")) 1))]
"" ""
"sub.w %0,%0\;bld %Z2,%Y1\;bst #0,%X0" "sub.w %0,%0\;bld %Z2,%Y1\;bst #0,%X0"
[(set_attr "cc" "clobber") [(set_attr "cc" "clobber")
(set_attr "length" "6")]) (set_attr "length" "6")])
(define_insn "insert_1" ;;
[(set (zero_extract:HI (match_operand:QI 0 "bit_operand" "+Ur") ;; Inverted loads with a 16bit destination.
(const_int 1) ;;
(match_operand:HI 1 "immediate_operand" "i")) ;; Yes, all four cases are needed.
(zero_extract:HI (match_operand:QI 2 "bit_operand" "Ur") ;;
(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 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 "cc" "clobber")
(set_attr "length" "4")]) (set_attr "length" "8")])
;; This is how combine canonicalizes this pattern. This is perhaps a bug (define_insn ""
;; in combine.c, but there is no problem with writing it this way so we do. [(set (match_operand:HI 0 "register_operand" "=&r")
(define_insn "extract_insert_1" (and:HI (not:HI
[(set (zero_extract:QI (match_operand:QI 0 "bit_operand" "+Ur") (subreg:HI
(const_int 1) (lshiftrt:SI
(match_operand:HI 1 "immediate_operand" "i")) (match_operand:SI 1 "register_operand" "Ur")
(lshiftrt:QI (match_operand:QI 2 "bit_operand" "Ur") (match_operand:SI 2 "const_int_operand" "n")) 1))
(match_operand:HI 3 "immediate_operand" "i")))] (const_int 1)))]
"" "INTVAL (operands[2]) < 16"
"bld %Z3,%Y2\;bst %Z1,%Y0; ei1" "sub.w %0,%0\;bild %Z2,%Y1\;bst #0,%X0"
[(set_attr "cc" "clobber") [(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") ;; Normal loads with a 32bit destination.
(match_operator:HI 4 "bit_operator" ;;
[(zero_extract:HI (match_operand:QI 1 "bit_operand" "Ur") ;; Yes, all three cases are needed.
(const_int 1) ;;
(match_operand:HI 2 "immediate_operand" "i")) (define_insn ""
(match_operand:HI 3 "bit_operand" "0")]))] [(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 "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" (define_insn ""
[(set (match_operand:HI 0 "bit_operand" "=Ur") [(set (match_operand:SI 0 "register_operand" "=&r")
(match_operator:HI 4 "bit_operator" (and:SI (zero_extend:SI
[(zero_extract:HI (match_operand:HI 1 "bit_operand" "Ur") (lshiftrt:QI
(const_int 1) (match_operand:QI 1 "bit_operand" "Ur")
(match_operand:HI 2 "immediate_operand" "i")) (match_operand:QI 2 "const_int_operand" "n")))
(match_operand:HI 3 "bit_operand" "0")]))] (const_int 1)))]
"" ""
"bld %Z2,%Y1\;%b4 #0,%R0\;bst #0,%R0; bl2" "* return output_simode_bld (0, 0, operands);"
[(set_attr "cc" "clobber") [(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" (define_insn ""
[(set (match_operand:HI 0 "bit_operand" "=Ur") [(set (match_operand:SI 0 "register_operand" "=&r")
(match_operator:HI 5 "bit_operator" (and:SI (zero_extend:SI
[(zero_extract:HI (match_operand:QI 1 "bit_operand" "Ur") (lshiftrt:HI
(const_int 1) (match_operand:HI 1 "bit_operand" "Ur")
(match_operand:HI 2 "immediate_operand" "i")) (match_operand:HI 2 "const_int_operand" "n")))
(zero_extract:HI (match_operand:QI 3 "bit_operand" "Ur") (const_int 1)))]
(const_int 1) ""
(match_operand:HI 4 "immediate_operand" "i"))]))] "* return output_simode_bld (0, 0, operands);"
""
"bld %Z2,%Y1\;%b5 %Z4,%Y3\;bst #0,%R0; bl3"
[(set_attr "cc" "clobber") [(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") ;; Inverted loads with a 32bit destination.
(match_operator:HI 5 "bit_operator" ;;
[(zero_extract:HI (match_operand:HI 1 "bit_operand" "Ur") ;; Yes, all seven cases are needed.
(const_int 1) ;;
(match_operand:HI 2 "immediate_operand" "i")) (define_insn ""
(zero_extract:HI (match_operand:HI 3 "bit_operand" "Ur") [(set (match_operand:SI 0 "register_operand" "=&r")
(const_int 1) (and:SI (not:SI
(match_operand:HI 4 "immediate_operand" "i"))]))] (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 "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 (define_insn ""
;; in combine.c, but there is no problem with writing it this way so we do. [(set (match_operand:SI 0 "register_operand" "=&r")
(define_insn "bitlogical_3" (and:SI (not:SI
[(set (zero_extract:QI (match_operand:QI 0 "bit_operand" "+Ur") (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))
(const_int 1) (match_operand:SI 2 "p_operand" "P")))]
(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"))]))]
"" ""
"bld %Z3,%Y2\;%b6 %Z5,%Y4\;bst %Z1,%Y0; bl5" "* return output_simode_bld (1, 1, operands);"
[(set_attr "cc" "clobber") [(set_attr "cc" "clobber")
(set_attr "length" "6")]) (set (attr "length")
(if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0))
;; This is how combine canonicalizes this pattern. This is perhaps a bug (const_int 10)
;; in combine.c, but there is no problem with writing it this way so we do. (const_int 8)))])
(define_insn "bitnot_1" (define_insn ""
[(set (zero_extract:QI (match_operand:QI 0 "bit_operand" "=Ur") [(set (match_operand:SI 0 "register_operand" "=&r")
(const_int 1) (and:SI (not:SI
(match_operand:HI 1 "immediate_operand" "i")) (zero_extend:SI
(lshiftrt:QI (xor:QI (match_operand:QI 2 "bit_operand" "0") (lshiftrt:QI (match_operand:QI 1 "bit_operand" "Ur")
(match_operand:HI 3 "immediate_operand" "i")) (match_operand:QI 2 "const_int_operand" "n"))))
(match_operand:HI 4 "immediate_operand" "1")))] (const_int 1)))]
"GET_CODE (operands[3]) == CONST_INT && GET_CODE (operands[1]) == CONST_INT ""
&& exact_log2 (INTVAL (operands[3])) == INTVAL (operands[1])" "* return output_simode_bld (1, 0, operands);"
"bnot %Z1,%Y0" [(set_attr "cc" "clobber")
[(set_attr "cc" "none_0hit") (set (attr "length")
(set_attr "length" "2")]) (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, (define_insn ""
;; but I don't know why. --Jim [(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" (define_expand "insv"
[(set (zero_extract:HI (match_operand:QI 0 "bit_operand" "Ur") [(set (zero_extract:HI (match_operand:HI 0 "general_operand" "")
(match_operand:HI 1 "general_operand" "g") (match_operand:HI 1 "general_operand" "")
(match_operand:HI 2 "general_operand" "g")) (match_operand:HI 2 "general_operand" ""))
(zero_extract:HI (match_operand:QI 3 "bit_operand" "Ur") (match_operand:HI 3 "general_operand" ""))]
(const_int 1)
(const_int 0)))]
;; ??? This should have word mode which is SImode for the h8/300h.
"TARGET_H8300" "TARGET_H8300"
" "
{ {
/* We only have single bit bitfield instructions. */
if (INTVAL (operands[1]) != 1) if (INTVAL (operands[1]) != 1)
FAIL; FAIL;
/* ??? HACK ??? /* For now, we don't allow memory operands. */
This INSV pattern is wrong. It should use HImode for operand 3. if (GET_CODE (operands[0]) == MEM
Also, the zero_extract around operand 3 is superfluous and should be || GET_CODE (operands[3]) == MEM)
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)
FAIL; 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, (define_insn ""
;; but I don't know why. --Jim [(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" (define_expand "extzv"
[(set (match_operand:HI 0 "register_operand" "") [(set (match_operand:HI 0 "register_operand" "")
(zero_extract:HI (match_operand:QI 1 "bit_operand" "") (zero_extract:HI (match_operand:HI 1 "bit_operand" "")
(match_operand:HI 2 "general_operand" "g") (match_operand:HI 2 "general_operand" "")
(match_operand:HI 3 "general_operand" "g")))] (match_operand:HI 3 "general_operand" "")))]
;; ??? This should have word mode which is SImode for the h8/300h.
"TARGET_H8300" "TARGET_H8300"
" "
{ {
/* We only have single bit bitfield instructions. */
if (INTVAL (operands[2]) != 1) if (INTVAL (operands[2]) != 1)
FAIL; FAIL;
/* The bit_operand predicate accepts any memory during RTL generation, but /* For now, we don't allow memory operands. */
only 'U' memory afterwards, so if this is a MEM operand, we must force if (GET_CODE (operands[1]) == MEM)
it to be valid for 'U' by reloading the address. */ FAIL;
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;
}
}") }")
;; -----------------------------------------------------------------
;; STACK POINTER MANIPULATIONS
;; -----------------------------------------------------------------
;; This pattern is needed because there is no way on the H8/300 ;; BAND, BOR, and BXOR patterns
;; 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.
(define_insn "stack_pointer_manip" (define_insn ""
[(set (match_operand:HI 0 "register_operand" "=&ra") [(set (match_operand:HI 0 "bit_operand" "=Ur")
(plus:HI (match_operand:HI 1 "general_operand_src" "g") (match_operator:HI 4 "bit_operator"
(match_operand:HI 2 "register_operand" "ra")))] [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
"TARGET_H8300" (const_int 1)
"mov.w %T1,%T0\;add.w %T2,%T0" (match_operand:HI 2 "immediate_operand" "i"))
[(set_attr "length" "6") (match_operand:HI 3 "bit_operand" "0")]))]
(set_attr "cc" "set_zn_c0")]) ""
"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 ;; BLK moves
;; ------------------------------------------- ;; -------------------------------------------
...@@ -2203,7 +2336,7 @@ ...@@ -2203,7 +2336,7 @@
(define_peephole (define_peephole
[(set (match_operand:QI 0 "register_operand" "=r") [(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")))) (match_operand:HI 2 "immediate_operand" "n"))))
(set (match_operand:QI 3 "register_operand" "=r") (set (match_operand:QI 3 "register_operand" "=r")
(mem:QI (plus:HI (match_dup 1) (mem:QI (plus:HI (match_dup 1)
...@@ -2214,7 +2347,7 @@ ...@@ -2214,7 +2347,7 @@
(set_attr "cc" "set")]) (set_attr "cc" "set")])
(define_peephole (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:HI 2 "immediate_operand" "n")))
(match_operand:QI 0 "register_operand" "r")) (match_operand:QI 0 "register_operand" "r"))
(set (mem:QI (plus:HI (match_dup 1) (set (mem:QI (plus:HI (match_dup 1)
...@@ -2283,7 +2416,7 @@ ...@@ -2283,7 +2416,7 @@
(ior:QI (subreg:QI (ior:QI (subreg:QI
(ashift:HI (const_int 1) (ashift:HI (const_int 1)
(match_operand:HI 1 "nonmemory_operand" "ri") ) 0) (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" "mov.b %R2,%R0\;bset %X1,%R0"
[(set_attr "length" "4") [(set_attr "length" "4")
...@@ -2343,15 +2476,6 @@ ...@@ -2343,15 +2476,6 @@
[(set_attr "length" "2") [(set_attr "length" "2")
(set_attr "cc" "clobber")]) (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" (define_insn "fancybsetp3"
[(set (match_operand:QI 0 "bit_operand" "=Ur") [(set (match_operand:QI 0 "bit_operand" "=Ur")
(ior:QI (subreg:QI (ashift:HI (const_int 1) (ior:QI (subreg:QI (ashift:HI (const_int 1)
...@@ -2366,7 +2490,7 @@ ...@@ -2366,7 +2490,7 @@
[(set (match_operand:QI 0 "general_operand" "=r,U") [(set (match_operand:QI 0 "general_operand" "=r,U")
(ior:QI (subreg:QI (ashift:HI (const_int 1) (ior:QI (subreg:QI (ashift:HI (const_int 1)
(match_operand:QI 1 "register_operand" "r,r")) 0) (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" "mov.b %R2,%R0\;bset %X1,%R0"
[(set_attr "length" "4") [(set_attr "length" "4")
...@@ -2383,50 +2507,8 @@ ...@@ -2383,50 +2507,8 @@
[(set_attr "length" "2") [(set_attr "length" "2")
(set_attr "cc" "clobber")]) (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" (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) (const_int 1)
(match_operand 1 "immediate_operand" "n,n")) (match_operand 1 "immediate_operand" "n,n"))
(and:QI (not:QI (match_operand:QI 2 "bit_operand" "r,U")) (and:QI (not:QI (match_operand:QI 2 "bit_operand" "r,U"))
...@@ -2435,3 +2517,31 @@ ...@@ -2435,3 +2517,31 @@
"bld #0,%R2\;bist %1,%0" "bld #0,%R2\;bist %1,%0"
[(set_attr "length" "4") [(set_attr "length" "4")
(set_attr "cc" "clobber")]) (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")])
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