Commit 3b7d443c by Jeff Law

h8300.md: Add more comments about things which seem wrong...

        * h8300.md: Add more comments about things which seem
        wrong, stupid, or just don't make any sense yet.

        * h8300.c (adds_subs_operand): New function.
        (output_adds_subs): New function.
        * h8300.md (addhi3): Turn into a define_expand.
        (addhi3 using adds_subs): New pattern.
        (H8300 addhi): Derived from old addhi pattern.  Simplified.
        (H8300H addhi): Likewise.
        (addsi using adds_subs): New pattern.  Only used on H8300H.
        (addsi_h8300): Allow "a" registers as destination.
        (addsi_h8300h):  Simplify.  Allow "a" registers as destination.

        * h8300.md (bcs): New attribute type.
        (default_length): Compute correct length for bcs insns.
        (bcs_qiqi, bcs_hihi, bs_hiqi): Use new type and update
        to account for correct length computation.

        * h8300.md (movhi_internal): Demand at least one operand to
        be a register.
        (movsi_h8300): Optimize loading certain constants.
        (movsi_h8300h): Likewise.

        * h8300.h (NO_FUNCTION_CSE): Comment out.
        (FUNCTION_ARG_REGNO_P): Properly define for TARGET_QUICKCALL.
        (RETURN_IN_MEMORY): Don't return small structs in regs.

From-SVN: r11751
parent 2ca96cdf
......@@ -431,6 +431,89 @@ call_insn_operand (op, mode)
return 0;
}
int
adds_subs_operand (op, mode)
rtx op;
enum machine_mode mode;
{
if (GET_CODE (op) == CONST_INT)
{
if (INTVAL (op) <= 4 && INTVAL (op) >= 0)
return 1;
if (INTVAL (op) >= -4 && INTVAL (op) <= 0)
return 1;
if (TARGET_H8300H
&& INTVAL (op) != 7
&& (INTVAL (op) <= 8 || INTVAL (op) >= 0))
return 1;
if (TARGET_H8300H
&& INTVAL (op) != -7
&& (INTVAL (op) >= -8 || INTVAL (op) <= 0))
return 1;
}
return 0;
}
char *
output_adds_subs (operands)
rtx *operands;
{
int val = INTVAL (operands[2]);
/* First get the value into the range -4..4 inclusive.
The only way it can be out of this range is when TARGET_H8300H
is true, thus it is safe to use adds #4 and subs #4. */
if (val > 4)
{
output_asm_insn ("adds #4,%A0", operands);
val -= 4;
}
if (val < -4)
{
output_asm_insn ("subs #4,%A0", operands);
val += 4;
}
/* Handle case were val == 4 or val == -4 and we're compiling
for TARGET_H8300H. */
if (TARGET_H8300H && val == 4)
return "adds #4,%A0";
if (TARGET_H8300H && val == -4)
return "subs #4,%A0";
if (val > 2)
{
output_asm_insn ("adds #2,%A0", operands);
val -= 2;
}
if (val < -2)
{
output_asm_insn ("subs #2,%A0", operands);
val += 2;
}
/* val should be one or two now. */
if (val == 2)
return "adds #2,%A0";
if (val == -2)
return "subs #2,%A0";
/* val should be one now. */
if (val == 1)
return "adds #1,%A0";
if (val == -1)
return "subs #1,%A0";
/* In theory, this can't happen. */
abort ();
}
/* Return true if OP is a valid call operand, and OP represents
an operand for a small call (4 bytes instead of 6 bytes). */
......
......@@ -126,7 +126,7 @@ do { \
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
/* #define NO_FUNCTION_CSE */
/* Target machine storage layout */
......@@ -541,9 +541,8 @@ enum reg_class {
/* 1 if N is a possible register number for function argument passing.
On the H8, no registers are used in this way. */
/* ??? What about TARGET_QUICKCALL? */
#define FUNCTION_ARG_REGNO_P(N) 0
#define FUNCTION_ARG_REGNO_P(N) (TARGET_QUICKCALL ? N < 3 : 0)
/* Register in which address to store a structure value
is passed to a function. */
......@@ -551,8 +550,8 @@ enum reg_class {
#define STRUCT_VALUE 0
/* Return true if X should be returned in memory. */
/* ??? This will return small structs in regs. */
#define RETURN_IN_MEMORY(X) (GET_MODE_SIZE (TYPE_MODE (X)) > 4)
#define RETURN_IN_MEMORY(X) \
(TYPE_MODE (X) == BLKmode || GET_MODE_SIZE (TYPE_MODE (X)) > 4)
/* When defined, the compiler allows registers explicitly used in the
rtl to be used as spill registers but prevents the compiler from
......@@ -1342,3 +1341,4 @@ 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();
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