aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeff Law <law@gcc.gnu.org>1996-04-12 16:21:28 -0600
committerJeff Law <law@gcc.gnu.org>1996-04-12 16:21:28 -0600
commit15dc331ee63e6954f443a180978602c370a56af9 (patch)
tree300ab9e653a1e8db416e4d3fb48fc4fa6c4cc2b5 /gcc
parent7f6ae52483134446bd577fa998a1438a1f339fbb (diff)
downloadgcc-15dc331ee63e6954f443a180978602c370a56af9.zip
gcc-15dc331ee63e6954f443a180978602c370a56af9.tar.gz
gcc-15dc331ee63e6954f443a180978602c370a56af9.tar.bz2
h8300.c (print_operand): Handle new 'R' case for accessing the 8-bit area.
* h8300/h8300.c (print_operand): Handle new 'R' case for accessing the 8-bit area. Make code for 'Y' fall into code for 'R' when operand is not a register. Update some comments. (h8300_tiny_data_p): New function. (h8300_valid_machine_decl_attribute): Handle "tiny_data" attribute. * h8300/h8300.h (OK_FOR_U): Handle memory references into the 8-bit area. (ENCODE_SECTION_INFO): Mark SYMBOL_REFs which refer to the 8-bit area. * h8300/h8300.md (many patterns): Use 'R' rather than 'X' for operands that may be memory accesses into the 8-bit area. (btst pattern): New pattern to set the cc0 (zbit) based on data in the 8-bit area. * h8300/h8300.md (one_cmplsi2): Fix length computation for h8300h. From-SVN: r11707
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/h8300/h8300.c43
-rw-r--r--gcc/config/h8300/h8300.h15
-rw-r--r--gcc/config/h8300/h8300.md104
3 files changed, 110 insertions, 52 deletions
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index 9fa2416..062912b 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -706,6 +706,8 @@ const_costs (r, c)
'L' fake label, changed after used twice.
'M' turn a 'M' constant into its negative mod 2.
'P' if operand is incing/decing sp, print .w, otherwise .b.
+ 'R' print operand as a byte:8 address if appropriate, else fall back to
+ 'X' handling.
'S' print operand as a long word
'T' print operand as a word
'U' if operand is incing/decing sp, print l, otherwise nothing.
@@ -713,6 +715,7 @@ const_costs (r, c)
'W' find the clear bit, and print its number.
'X' print operand as a byte
'Y' print either l or h depending on whether last 'Z' operand < 8 or >= 8.
+ If this operand isn't a register, fall back to 'R' handling.
'Z' print int & 7.
'b' print the bit opcode
'c' print the ibit opcode
@@ -890,6 +893,7 @@ print_operand (file, x, code)
abort ();
fprintf (file, "#%d", bitint & 7);
break;
+ case 'R':
case 'X':
if (GET_CODE (x) == REG)
fprintf (file, "%s", byte_reg (x, 0));
@@ -902,7 +906,7 @@ print_operand (file, x, code)
if (GET_CODE (x) == REG)
fprintf (file, "%s%c", names_big[REGNO (x)], bitint > 7 ? 'h' : 'l');
else
- print_operand (file, x, 0);
+ print_operand (file, x, 'R');
bitint = -1;
break;
case 'Z':
@@ -1081,6 +1085,13 @@ print_operand (file, x, code)
case MEM:
fprintf (file, "@");
output_address (XEXP (x, 0));
+
+ /* If this is an 'R' operand (reference into the 8-bit area),
+ then specify a symbolic address as "foo:8". */
+ if (code == 'R'
+ && GET_CODE (XEXP (x, 0)) == SYMBOL_REF
+ && SYMBOL_REF_FLAG (XEXP (x, 0)))
+ fprintf (file, ":8");
break;
case CONST_INT:
@@ -2050,7 +2061,6 @@ fix_bit_operand (operands, what, type)
return 1;
}
-
/* Return nonzero if FUNC is an interrupt function as specified
by the "interrupt" attribute. */
@@ -2083,6 +2093,22 @@ h8300_funcvec_function_p (func)
return a != NULL_TREE;
}
+/* Return nonzero if DECL is a variable that's in the tiny
+ data area. */
+
+int
+h8300_tiny_data_p (decl)
+ tree decl;
+{
+ tree a;
+
+ if (TREE_CODE (decl) != VAR_DECL)
+ return 0;
+
+ a = lookup_attribute ("tiny_data", DECL_MACHINE_ATTRIBUTES (decl));
+ return a != NULL_TREE;
+}
+
/* Return nonzero if ATTR is a valid attribute for DECL.
ATTRIBUTES are any existing attributes and ARGS are the arguments
supplied with ATTR.
@@ -2108,6 +2134,19 @@ h8300_valid_machine_decl_attribute (decl, attributes, attr, args)
if (is_attribute_p ("interrupt_handler", attr)
|| is_attribute_p ("function_vector", attr))
return TREE_CODE (decl) == FUNCTION_DECL;
+
+ if (is_attribute_p ("tiny_data", attr)
+ && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
+ {
+ if (DECL_INITIAL (decl) == NULL_TREE)
+ {
+ warning ("Only initialized variables can be placed into the 8-bit area.");
+ return 0;
+ }
+ DECL_SECTION_NAME (decl) = build_string (8, ".eight");
+ return 1;
+ }
+
return 0;
}
diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h
index 78b006e..c6d6b92 100644
--- a/gcc/config/h8300/h8300.h
+++ b/gcc/config/h8300/h8300.h
@@ -790,11 +790,15 @@ struct rtx_def *function_arg();
#endif
/* Extra constraints - 'U' if for an operand valid for a bset
- destination; i.e. a register or register indirect target. */
+ destination; i.e. a register, register indirect, or the
+ eightbit memory region (a SYMBOL_REF with the SYMBOL_REF_FLAG
+ set. */
#define OK_FOR_U(OP) \
((GET_CODE (OP) == REG && REG_OK_FOR_BASE_P (OP)) \
|| (GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG \
- && REG_OK_FOR_BASE_P (XEXP (OP, 0))))
+ && REG_OK_FOR_BASE_P (XEXP (OP, 0))) \
+ || (GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == SYMBOL_REF \
+ && SYMBOL_REF_FLAG (XEXP (OP, 0))))
#define EXTRA_CONSTRAINT(OP, C) \
((C) == 'U' ? OK_FOR_U (OP) : 0)
@@ -1085,8 +1089,11 @@ dtors_section() \
through the function vector, the SYMBOL_REF_FLAG in the rtl
so the call patterns can generate the correct code. */
#define ENCODE_SECTION_INFO(DECL) \
- if (TREE_CODE (DECL) == FUNCTION_DECL \
- && h8300_funcvec_function_p (DECL)) \
+ if ((TREE_CODE (DECL) == FUNCTION_DECL \
+ && h8300_funcvec_function_p (DECL)) \
+ || ((TREE_STATIC (DECL) || DECL_EXTERNAL (DECL)) \
+ && TREE_CODE (DECL) == VAR_DECL \
+ && h8300_tiny_data_p (DECL))) \
SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1;
/* How to refer to registers in assembler output.
diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md
index 4555fcb..ccd51b5d 100644
--- a/gcc/config/h8300/h8300.md
+++ b/gcc/config/h8300/h8300.md
@@ -38,7 +38,8 @@
;; 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
-;; would be more efficient time and space-wise.
+;; would be more efficient time and space-wise. Similar sequences
+;; can be found using bit-set insns dec, etc
(define_attr "type" "branch,return,call,arith,move,float,multi"
@@ -108,10 +109,10 @@
|| register_operand (operands[1], QImode)"
"@
sub.b %X0,%X0
- mov.b %X1,%X0
- mov.b %X1,%X0
- mov.b %X1,%X0
- mov.b %X1,%X0"
+ mov.b %R1,%X0
+ mov.b %X1,%R0
+ mov.b %R1,%X0
+ mov.b %X1,%R0"
[(set_attr "type" "move")
(set_attr_alternative "length"
[(const_int 2) (const_int 2) (const_int 2)
@@ -140,7 +141,7 @@
"@
sub.b %X0,%X0
mov.b %X1,%X0
- mov.b %X1,%X0"
+ mov.b %R1,%X0"
[(set_attr "type" "move")
(set_attr_alternative "length"
[(const_int 2) (const_int 2)
@@ -411,6 +412,15 @@
;; TEST INSTRUCTIONS
;; ----------------------------------------------------------------------
+(define_insn ""
+ [(set (cc0) (and:QI (match_operand:QI 0 "bit_operand" "Ur")
+ (match_operand:QI 1 "o_operand" "O")))]
+ ""
+ "btst %W1,%R0"
+ [(set_attr "type" "arith")
+ (set_attr "length" "2")
+ (set_attr "cc" "set_zn_c0")])
+
(define_insn "tstqi"
[(set (cc0) (match_operand:QI 0 "general_operand" "ra"))]
""
@@ -778,7 +788,7 @@
"register_operand (operands[0], QImode) || o_operand (operands[2], QImode)"
"@
and %X2,%X0
- bclr %W2,%X0"
+ bclr %W2,%R0"
[(set_attr "type" "arith")
(set_attr "length" "2,4")
(set_attr "cc" "set,none_0hit")])
@@ -843,7 +853,7 @@
(match_operand:QI 2 "nonmemory_operand" "P,rn")))]
"register_operand (operands[0], QImode) || p_operand (operands[2], QImode)"
"@
- bset %V2,%X0
+ bset %V2,%R0
or %X2,%X0"
[(set_attr "type" "arith")
(set_attr "length" "4,2")
@@ -936,7 +946,7 @@
"register_operand (operands[0], QImode) || p_operand (operands[2], QImode)"
"@
xor %X2,%X0
- bnot %V2,%X0"
+ bnot %V2,%R0"
[(set_attr "type" "arith")
(set_attr "length" "2,4")
(set_attr "cc" "set,none_0hit")])
@@ -1099,9 +1109,12 @@
return \"not %S0\";
}"
[(set_attr "type" "arith")
-;; ??? length is wrong for 300h
- (set_attr "length" "8")
- (set_attr "cc" "clobber")])
+ (set_attr "cc" "clobber")
+ (set (attr "length")
+ (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0))
+ (const_int 8)
+ (const_int 4)))])
+
;; ----------------------------------------------------------------------
;; JUMP INSTRUCTIONS
@@ -1230,7 +1243,6 @@
(pc)
(label_ref (match_operand 0 "" ""))))]
""
-;; ??? We don't take advantage of 16 bit relative jumps in the 300h.
"*
{
/* If we erroneously deleted a compare insn (which can happen if we need
@@ -1389,14 +1401,14 @@
return \"mov.b #0,%t0\";
if (TARGET_H8300)
- return \"mov.b %X1,%s0\;mov.b #0,%t0\";
+ return \"mov.b %R1,%s0\;mov.b #0,%t0\";
else
{
/* ??? See how often this gets optimized. */
if (REG_P (operands[1]) && (REGNO (operands[1]) == REGNO (operands[0])))
return \"extu.w %T0\";
else
- return \"mov.b %X1,%s0\;extu.w %T0\";
+ return \"mov.b %R1,%s0\;extu.w %T0\";
}
}"
[(set_attr "type" "multi")
@@ -1433,7 +1445,7 @@
if (REG_P (operands[1]) && (REGNO (operands[1]) == REGNO (operands[0])))
return \"bld #7,%s0\;subx %t0,%t0\";
else
- return \"mov.b %X1,%s0\;bld #7,%s0\;subx %t0,%t0\";
+ return \"mov.b %R1,%s0\;bld #7,%s0\;subx %t0,%t0\";
}
else
{
@@ -1441,7 +1453,7 @@
if (REG_P (operands[1]) && (REGNO (operands[1]) == REGNO (operands[0])))
return \"exts.w %T0\";
else
- return \"mov.b %X1,%s0\;exts.w %T0\";
+ return \"mov.b %R1,%s0\;exts.w %T0\";
}
}"
[(set_attr "type" "multi")
@@ -1690,11 +1702,11 @@
{
output_asm_insn(\"bld %Z3,%Y2\", operands);
if (get_attr_length (insn) == 2)
- return \"%d1 %l0\";
+ return \"b%d1 %l0\";
else if (get_attr_length (insn) == 4)
- return \"%d1 %l0:16\";
+ return \"b%d1 %l0:16\";
else
- return \"%g1 %L0\;jmp @%l0\;%L0:\";
+ return \"b%g1 %L0\;jmp @%l0\;%L0:\";
}"
[(set_attr "type" "branch")
(set_attr "cc" "clobber")])
@@ -1714,11 +1726,11 @@
{
output_asm_insn(\"bld %Z3,%Y2\", operands);
if (get_attr_length (insn) == 2)
- return \"%d1 %l0\";
+ return \"b%d1 %l0\";
else if (get_attr_length (insn) == 4)
- return \"%d1 %l0:16\";
+ return \"b%d1 %l0:16\";
else
- return \"%g1 %L0\;jmp @%l0\;%L0:\";
+ return \"b%g1 %L0\;jmp @%l0\;%L0:\";
}"
[(set_attr "type" "branch")
(set_attr "cc" "clobber")])
@@ -1749,7 +1761,7 @@
(const_int 1)
(const_int 0)))]
""
- "bld #0,%X2\;bst %Z1,%Y0 ; i1")
+ "bld #0,%R2\;bst %Z1,%Y0 ; i1")
;; 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.
@@ -1772,7 +1784,7 @@
(match_operand:HI 2 "immediate_operand" "i"))
(match_operand:HI 3 "bit_operand" "0")]))]
""
- "bld %Z2,%Y1\;%b4 #0,%X0\;bst #0,%X0; bl1")
+ "bld %Z2,%Y1\;%b4 #0,%R0\;bst #0,%R0; bl1")
(define_insn "bitlogical_1_hi"
[(set (match_operand:HI 0 "bit_operand" "=Ur")
@@ -1782,7 +1794,7 @@
(match_operand:HI 2 "immediate_operand" "i"))
(match_operand:HI 3 "bit_operand" "0")]))]
""
- "bld %Z2,%Y1\;%b4 #0,%X0\;bst #0,%X0; bl2")
+ "bld %Z2,%Y1\;%b4 #0,%R0\;bst #0,%R0; bl2")
(define_insn "bitlogical_2"
[(set (match_operand:HI 0 "bit_operand" "=Ur")
@@ -1794,7 +1806,7 @@
(const_int 1)
(match_operand:HI 4 "immediate_operand" "i"))]))]
""
- "bld %Z2,%Y1\;%b5 %Z4,%Y3\;bst #0,%X0; bl3")
+ "bld %Z2,%Y1\;%b5 %Z4,%Y3\;bst #0,%R0; bl3")
(define_insn "bitlogical_2_hi"
[(set (match_operand:HI 0 "bit_operand" "=Ur")
@@ -1806,7 +1818,7 @@
(const_int 1)
(match_operand:HI 4 "immediate_operand" "i"))]))]
""
- "bld %Z2,%Y1\;%b5 %Z4,%Y3\;bst #0,%X0; bl3")
+ "bld %Z2,%Y1\;%b5 %Z4,%Y3\;bst #0,%R0; bl3")
;; 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.
@@ -2091,7 +2103,7 @@
(subreg:QI (match_operand:HI 1 "register_operand" "ri") 0)) 0)
(match_dup 0)))]
""
- "bset %X1,%X0")
+ "bset %X1,%R0")
(define_insn "fancybset"
[(set (match_operand:QI 0 "bit_operand" "=Ur")
@@ -2100,7 +2112,7 @@
(match_operand:HI 1 "nonmemory_operand" "ri") ) 0)
(match_operand:QI 2 "general_operand" "Ur")))]
""
- "mov.b %X2,%X0\;bset %X1,%X0")
+ "mov.b %R2,%R0\;bset %X1,%R0")
(define_insn "fancybclr4"
[(set (match_operand:QI 0 "general_operand" "=Ur,Ur")
@@ -2112,8 +2124,8 @@
(clobber (match_scratch:HI 3 "=X,&r"))]
""
"@
- bclr %X2,%X0; l1
- mov.b %X1,%X3\;mov.b %3,%0\;bclr %X2,%X0; l3")
+ bclr %X2,%R0; l1
+ mov.b %R1,%X3\;mov.b %3,%0\;bclr %X2,%R0; l3")
(define_insn "fancybclr5"
[(set (match_operand:QI 0 "general_operand" "=Ur,Ur")
@@ -2125,8 +2137,8 @@
(clobber (match_scratch:HI 3 "=X,&r"))]
""
"@
- bclr %X2,%X0; l1
- mov.b %X1,%X3\;mov.b %3,%0\;bclr %X2,%X0;l2")
+ bclr %X2,%R0; l1
+ mov.b %R1,%X3\;mov.b %3,%0\;bclr %X2,%R0;l2")
(define_insn "fancybclr2"
[(set (match_operand:QI 0 "general_operand" "=U,r")
@@ -2136,7 +2148,7 @@
(match_operand:HI 2 "nonmemory_operand" "ri,ri") ) 0)
(match_operand:QI 1 "general_operand" "0,0")))]
""
- "bclr %X2,%X0")
+ "bclr %X2,%R0")
(define_insn "fancybclr3"
[(set (match_operand:QI 0 "general_operand" "=U,r")
@@ -2146,7 +2158,7 @@
(match_operand:QI 2 "nonmemory_operand" "ri,ri")) 0)
(match_operand:QI 1 "general_operand" "0,0")))]
""
- "bclr %X2,%X0")
+ "bclr %X2,%R0")
(define_insn "fancybclr"
[(set (match_operand:QI 0 "general_operand" "=r")
@@ -2161,7 +2173,7 @@
(match_operand:QI 1 "register_operand" "r")) 0)
(match_operand:QI 2 "bit_operand" "0")))]
""
- "bset %X1,%X0")
+ "bset %X1,%R0")
(define_insn "fancybsetp2"
[(set (match_operand:QI 0 "general_operand" "=r,U")
@@ -2169,7 +2181,7 @@
(match_operand:QI 1 "register_operand" "r,r")) 0)
(match_operand:QI 2 "general_operand" "U,r")))]
""
- "mov.b %X2,%X0\;bset %X1,%X0")
+ "mov.b %R2,%R0\;bset %X1,%R0")
(define_insn "fancybnot"
[(set (match_operand:QI 0 "bit_operand" "=Ur")
@@ -2178,7 +2190,7 @@
(match_operand:QI 2 "bit_operand" "0")))]
""
- "bnot %X1,%X0")
+ "bnot %X1,%R0")
(define_insn "fancy_btst"
[(set (pc)
@@ -2192,11 +2204,11 @@
"*
{
if (get_attr_length (insn) == 2)
- return \"btst %X2,%X1\;beq %l0\";
+ return \"btst %X2,%R1\;beq %l0\";
else if (get_attr_length (insn) == 4)
- return \"btst %X2,%X1\;beq %l0:16\";
+ return \"btst %X2,%R1\;beq %l0:16\";
else
- return \"btst %X2,%X1\;bne %L1\;jmp @%l0\;%L1:\";
+ return \"btst %X2,%R1\;bne %L1\;jmp @%l0\;%L1:\";
}"
[(set_attr "type" "branch")
(set_attr "cc" "clobber")])
@@ -2213,11 +2225,11 @@
"*
{
if (get_attr_length (insn) == 2)
- return \"btst %X2,%X1\;bne %l0\";
+ return \"btst %X2,%R1\;bne %l0\";
else if (get_attr_length (insn) == 4)
- return \"btst %X2,%X1\;bne %l0:16\";
+ return \"btst %X2,%R1\;bne %l0:16\";
else
- return \"btst %X2,%X1\;beq %L1\;jmp @%l0\;%L1:\";
+ return \"btst %X2,%R1\;beq %L1\;jmp @%l0\;%L1:\";
}"
[(set_attr "type" "branch")
(set_attr "cc" "clobber")])
@@ -2229,7 +2241,7 @@
(and:QI (not:QI (match_operand:QI 2 "bit_operand" "r,U"))
(const_int 1)))]
""
- "bld #0,%X2\;bist %1,%0"
+ "bld #0,%R2\;bist %1,%0"
[(set_attr "type" "arith")
(set_attr "length" "4")
(set_attr "cc" "clobber")])