aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeff Law <law@gcc.gnu.org>1996-04-28 23:27:26 -0600
committerJeff Law <law@gcc.gnu.org>1996-04-28 23:27:26 -0600
commitbd93f126954387c1e553202c75fb3c9a6f981315 (patch)
treef890c366b72af7d227b238f089c6ad3460b98b21 /gcc
parent2ac42d3ac2e7382a35b5bf82be9fda8fa1854520 (diff)
downloadgcc-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.c30
-rw-r--r--gcc/config/h8300/h8300.h38
-rw-r--r--gcc/config/h8300/h8300.md736
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")])
+