Commit 15dc331e by Jeff Law

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
parent 7f6ae524
......@@ -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;
}
......@@ -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.
......
......@@ -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")])
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