constraints.md: New file.
* config/h8300/constraints.md: New file. * config/h8300/h8300.md: Include it. Use satisfies_constraint_J, satisfies_constraint_L, and satisfies_constraint_N for peephole2s. (*tst_extzv_1_n, *tstsi_variable_bit_qi): Use satisfies_constraint_U. * config/h8300/predicates.md (bit_operand): Likewise. (incdec_operand): Use satisfies_constraint_M and satisfies_constraint_O. Don't use C code block. * config/h8300/h8300-protos.h (h8300_reg_class_from_letter): Delete. * config/h8300/h8300.c (h8300_reg_class_from_letter): Delete. (compute_mov_length): Use satisfies_constraint_G. (fix_bit_operand): Use satisfies_constraint_U. * config/h8300/h8300.h (REG_CLASS_FROM_LETTER): Delete. (CONST_OK_FOR_I, CONST_OK_FOR_J, CONST_OK_FOR_L): Delete. (CONST_OK_FOR_M, CONST_OK_FOR_N, CONST_OK_FOR_O): Delete. (CONST_OK_FOR_Ppositive, CONST_OK_FOR_Pnegative): Delete. (CONST_OK_FOR_P, CONSTRAINT_LEN_FOR_P): Delete. (CONST_OK_FOR_CONSTRAINT_P, CONST_OK_FOR_LETTER_P): Delete. (CONST_DOUBLE_OK_FOR_LETTER_P): Delete. (OK_FOR_Q, OK_FOR_R, OK_FOR_S, OK_FOR_T, OK_FOR_U, OK_FOR_WU): Delete. (OK_FOR_W, CONSTRAINT_LEN_FOR_W, OK_FOR_Y2, OK_FOR_Y0): Delete. (OK_FOR_Y, CONSTRAINT_LEN_FOR_Y, OK_FOR_Z): Delete. (EXTRA_CONSTRAINT_STR, CONSTRAINT_LEN): Delete. (EXTRA_MEMORY_CONSTRAINT): Delete. From-SVN: r171851
This commit is contained in:
parent
c1c0e8e1d3
commit
ceaaaeabf6
@ -1,3 +1,29 @@
|
|||||||
|
2011-04-01 Nathan Froyd <froydnj@codesourcery.com>
|
||||||
|
|
||||||
|
* config/h8300/constraints.md: New file.
|
||||||
|
* config/h8300/h8300.md: Include it. Use satisfies_constraint_J,
|
||||||
|
satisfies_constraint_L, and satisfies_constraint_N for peephole2s.
|
||||||
|
(*tst_extzv_1_n, *tstsi_variable_bit_qi): Use satisfies_constraint_U.
|
||||||
|
* config/h8300/predicates.md (bit_operand): Likewise.
|
||||||
|
(incdec_operand): Use satisfies_constraint_M and
|
||||||
|
satisfies_constraint_O. Don't use C code block.
|
||||||
|
* config/h8300/h8300-protos.h (h8300_reg_class_from_letter): Delete.
|
||||||
|
* config/h8300/h8300.c (h8300_reg_class_from_letter): Delete.
|
||||||
|
(compute_mov_length): Use satisfies_constraint_G.
|
||||||
|
(fix_bit_operand): Use satisfies_constraint_U.
|
||||||
|
* config/h8300/h8300.h (REG_CLASS_FROM_LETTER): Delete.
|
||||||
|
(CONST_OK_FOR_I, CONST_OK_FOR_J, CONST_OK_FOR_L): Delete.
|
||||||
|
(CONST_OK_FOR_M, CONST_OK_FOR_N, CONST_OK_FOR_O): Delete.
|
||||||
|
(CONST_OK_FOR_Ppositive, CONST_OK_FOR_Pnegative): Delete.
|
||||||
|
(CONST_OK_FOR_P, CONSTRAINT_LEN_FOR_P): Delete.
|
||||||
|
(CONST_OK_FOR_CONSTRAINT_P, CONST_OK_FOR_LETTER_P): Delete.
|
||||||
|
(CONST_DOUBLE_OK_FOR_LETTER_P): Delete.
|
||||||
|
(OK_FOR_Q, OK_FOR_R, OK_FOR_S, OK_FOR_T, OK_FOR_U, OK_FOR_WU): Delete.
|
||||||
|
(OK_FOR_W, CONSTRAINT_LEN_FOR_W, OK_FOR_Y2, OK_FOR_Y0): Delete.
|
||||||
|
(OK_FOR_Y, CONSTRAINT_LEN_FOR_Y, OK_FOR_Z): Delete.
|
||||||
|
(EXTRA_CONSTRAINT_STR, CONSTRAINT_LEN): Delete.
|
||||||
|
(EXTRA_MEMORY_CONSTRAINT): Delete.
|
||||||
|
|
||||||
2011-04-01 Andrew Pinski <pinskia@gmail.com>
|
2011-04-01 Andrew Pinski <pinskia@gmail.com>
|
||||||
Michael Meissner <meissner@linux.vnet.ibm.com>
|
Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||||
|
|
||||||
|
214
gcc/config/h8300/constraints.md
Normal file
214
gcc/config/h8300/constraints.md
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
;; Constraint definitions for Renesas H8/300.
|
||||||
|
;; Copyright (C) 2011 Free Software Foundation, Inc.
|
||||||
|
;;
|
||||||
|
;; This file is part of GCC.
|
||||||
|
;;
|
||||||
|
;; GCC is free software; you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
;; any later version.
|
||||||
|
;;
|
||||||
|
;; GCC is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
;;
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with GCC; see the file COPYING3. If not see
|
||||||
|
;; <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;; Register constraints.
|
||||||
|
(define_register_constraint "a" "MAC_REGS"
|
||||||
|
"@internal")
|
||||||
|
|
||||||
|
(define_register_constraint "c" "COUNTER_REGS"
|
||||||
|
"@internal")
|
||||||
|
|
||||||
|
;; Some patterns need to use er6 as a scratch register. This is
|
||||||
|
;; difficult to arrange since er6 is the frame pointer and usually can't
|
||||||
|
;; be spilled.
|
||||||
|
|
||||||
|
;; Such patterns should define two alternatives, one which allows only
|
||||||
|
;; er6 and one which allows any general register. The former
|
||||||
|
;; alternative should have a 'd' constraint while the latter should be
|
||||||
|
;; disparaged and use 'D'.
|
||||||
|
|
||||||
|
;; Normally, 'd' maps to DESTINATION_REGS and 'D' maps to GENERAL_REGS.
|
||||||
|
;; However, there are cases where they should be NO_REGS:
|
||||||
|
|
||||||
|
;; - 'd' should be NO_REGS when reloading a function that uses the
|
||||||
|
;; frame pointer. In this case, DESTINATION_REGS won't contain any
|
||||||
|
;; spillable registers, so the first alternative can't be used.
|
||||||
|
|
||||||
|
;; - -fno-omit-frame-pointer means that the frame pointer will
|
||||||
|
;; always be in use. It's therefore better to map 'd' to NO_REGS
|
||||||
|
;; before reload so that register allocator will pick the second
|
||||||
|
;; alternative.
|
||||||
|
|
||||||
|
;; - we would like 'D' to be be NO_REGS when the frame pointer isn't
|
||||||
|
;; live, but we the frame pointer may turn out to be needed after
|
||||||
|
;; we start reload, and then we may have already decided we don't
|
||||||
|
;; have a choice, so we can't do that. Forcing the register
|
||||||
|
;; allocator to use er6 if possible might produce better code for
|
||||||
|
;; small functions: it's more efficient to save and restore er6 in
|
||||||
|
;; the prologue & epilogue than to do it in a define_split.
|
||||||
|
;; Hopefully disparaging 'D' will have a similar effect, without
|
||||||
|
;; forcing a reload failure if the frame pointer is found to be
|
||||||
|
;; needed too late.
|
||||||
|
|
||||||
|
(define_register_constraint "d"
|
||||||
|
"(!flag_omit_frame_pointer && !reload_completed
|
||||||
|
? NO_REGS
|
||||||
|
: (frame_pointer_needed && reload_in_progress
|
||||||
|
? NO_REGS
|
||||||
|
: DESTINATION_REGS))"
|
||||||
|
"@internal")
|
||||||
|
|
||||||
|
(define_register_constraint "D" "GENERAL_REGS"
|
||||||
|
"@internal")
|
||||||
|
|
||||||
|
(define_register_constraint "f" "SOURCE_REGS"
|
||||||
|
"@internal")
|
||||||
|
|
||||||
|
;; Integer constraints.
|
||||||
|
(define_constraint "I"
|
||||||
|
"Integer zero."
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "ival == 0")))
|
||||||
|
|
||||||
|
(define_constraint "J"
|
||||||
|
"An integer with its low byte clear."
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "(ival & 0xff) == 0")))
|
||||||
|
|
||||||
|
(define_constraint "L"
|
||||||
|
"1, 2 or 4 on the H8300H or S; 1 or 2 otherwise."
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(if_then_else (match_test "TARGET_H8300H || TARGET_H8300S")
|
||||||
|
(match_test "ival == 1 || ival == 2 || ival == 4")
|
||||||
|
(match_test "ival == 1 || ival == 2"))))
|
||||||
|
|
||||||
|
(define_constraint "M"
|
||||||
|
"Integer 1 or 2."
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "ival == 1 || ival == 2")))
|
||||||
|
|
||||||
|
(define_constraint "N"
|
||||||
|
"-1, -2, or -4 on the H8300H or S; -1 or -2 otherwise."
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(if_then_else (match_test "TARGET_H8300H || TARGET_H8300S")
|
||||||
|
(match_test "ival == -1 || ival == -2 || ival == -4")
|
||||||
|
(match_test "ival == -1 || ival == -2"))))
|
||||||
|
|
||||||
|
(define_constraint "O"
|
||||||
|
"Integer -1 or -2."
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "ival == -1 || ival == -2")))
|
||||||
|
|
||||||
|
(define_constraint "P1>X"
|
||||||
|
"A positive, non-zero integer that fits in 1 bits."
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "TARGET_H8300SX")
|
||||||
|
(match_test "IN_RANGE (ival, 1, (1 << 1) - 1)")))
|
||||||
|
|
||||||
|
(define_constraint "P3>X"
|
||||||
|
"A positive, non-zero integer that fits in 3 bits."
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "TARGET_H8300SX")
|
||||||
|
(match_test "IN_RANGE (ival, 1, (1 << 3) - 1)")))
|
||||||
|
|
||||||
|
(define_constraint "P4>X"
|
||||||
|
"A positive, non-zero integer that fits in 4 bits."
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "TARGET_H8300SX")
|
||||||
|
(match_test "IN_RANGE (ival, 1, (1 << 4) - 1)")))
|
||||||
|
|
||||||
|
(define_constraint "P5>X"
|
||||||
|
"A positive, non-zero integer that fits in 5 bits."
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "TARGET_H8300SX")
|
||||||
|
(match_test "IN_RANGE (ival, 1, (1 << 5) - 1)")))
|
||||||
|
|
||||||
|
(define_constraint "P8>X"
|
||||||
|
"A positive, non-zero integer that fits in 8 bits."
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "TARGET_H8300SX")
|
||||||
|
(match_test "IN_RANGE (ival, 1, (1 << 8) - 1)")))
|
||||||
|
|
||||||
|
(define_constraint "P3<X"
|
||||||
|
"A negative, non-zero integer that fits in 3 bits."
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "TARGET_H8300SX")
|
||||||
|
(match_test "IN_RANGE (ival, (-(1 << 3)) + 1, -1)")))
|
||||||
|
|
||||||
|
;; Floating-point constraints.
|
||||||
|
(define_constraint "G"
|
||||||
|
"Single-float zero."
|
||||||
|
(and (match_code "const_double")
|
||||||
|
(match_test "op == CONST0_RTX (SFmode)")))
|
||||||
|
|
||||||
|
;; Extra constraints.
|
||||||
|
(define_constraint "Q"
|
||||||
|
"@internal"
|
||||||
|
(and (match_test "TARGET_H8300SX")
|
||||||
|
(match_operand 0 "memory_operand")))
|
||||||
|
|
||||||
|
(define_constraint "R"
|
||||||
|
"@internal"
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "!h8300_shift_needs_scratch_p (ival, QImode)")))
|
||||||
|
|
||||||
|
(define_constraint "S"
|
||||||
|
"@internal"
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "!h8300_shift_needs_scratch_p (ival, HImode)")))
|
||||||
|
|
||||||
|
(define_constraint "T"
|
||||||
|
"@internal"
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "!h8300_shift_needs_scratch_p (ival, SImode)")))
|
||||||
|
|
||||||
|
(define_constraint "U"
|
||||||
|
"An operand valid for a bset destination."
|
||||||
|
(ior (and (match_code "reg")
|
||||||
|
(match_test "REG_OK_FOR_BASE_P (op)"))
|
||||||
|
(and (match_code "mem")
|
||||||
|
(match_code "reg" "0")
|
||||||
|
(match_test "REG_OK_FOR_BASE_P (XEXP (op, 0))"))
|
||||||
|
(and (match_code "mem")
|
||||||
|
(match_code "symbol_ref" "0")
|
||||||
|
(match_test "TARGET_H8300S"))
|
||||||
|
(and (match_code "mem")
|
||||||
|
(match_code "const" "0")
|
||||||
|
(match_code "plus" "00")
|
||||||
|
(match_code "symbol_ref" "000")
|
||||||
|
(match_code "const_int" "001")
|
||||||
|
(ior (match_test "TARGET_H8300S")
|
||||||
|
(match_test "SYMBOL_REF_FLAG (XEXP (XEXP (XEXP (op, 0), 0), 0))")))
|
||||||
|
(and (match_code "mem")
|
||||||
|
(match_test "h8300_eightbit_constant_address_p (XEXP (op, 0))"))
|
||||||
|
(and (match_code "mem")
|
||||||
|
(ior (match_test "TARGET_H8300S")
|
||||||
|
(match_test "TARGET_H8300SX"))
|
||||||
|
(match_code "const_int" "0"))))
|
||||||
|
|
||||||
|
(define_memory_constraint "WU"
|
||||||
|
"@internal"
|
||||||
|
(and (match_code "mem")
|
||||||
|
(match_test "satisfies_constraint_U (op)")))
|
||||||
|
|
||||||
|
(define_constraint "Y0"
|
||||||
|
"@internal"
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "exact_log2 (~ival & 0xff) != -1")))
|
||||||
|
|
||||||
|
(define_constraint "Y2"
|
||||||
|
"@internal"
|
||||||
|
(and (match_code "const_int")
|
||||||
|
(match_test "exact_log2 (ival & 0xff) != -1")))
|
||||||
|
|
||||||
|
(define_constraint "Z"
|
||||||
|
"@internal"
|
||||||
|
(and (match_test "TARGET_H8300SX")
|
||||||
|
(match_code "mem")
|
||||||
|
(match_test "CONSTANT_P (XEXP (op, 0))")))
|
@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see
|
|||||||
#include "diagnostic-core.h"
|
#include "diagnostic-core.h"
|
||||||
#include "c-family/c-pragma.h" /* ??? */
|
#include "c-family/c-pragma.h" /* ??? */
|
||||||
#include "tm_p.h"
|
#include "tm_p.h"
|
||||||
|
#include "tm-constrs.h"
|
||||||
#include "ggc.h"
|
#include "ggc.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "target-def.h"
|
#include "target-def.h"
|
||||||
@ -421,71 +422,6 @@ h8300_option_override (void)
|
|||||||
flag_strict_volatile_bitfields = 1;
|
flag_strict_volatile_bitfields = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implement REG_CLASS_FROM_LETTER.
|
|
||||||
|
|
||||||
Some patterns need to use er6 as a scratch register. This is
|
|
||||||
difficult to arrange since er6 is the frame pointer and usually
|
|
||||||
can't be spilled.
|
|
||||||
|
|
||||||
Such patterns should define two alternatives, one which allows only
|
|
||||||
er6 and one which allows any general register. The former alternative
|
|
||||||
should have a 'd' constraint while the latter should be disparaged and
|
|
||||||
use 'D'.
|
|
||||||
|
|
||||||
Normally, 'd' maps to DESTINATION_REGS and 'D' maps to GENERAL_REGS.
|
|
||||||
However, there are cases where they should be NO_REGS:
|
|
||||||
|
|
||||||
- 'd' should be NO_REGS when reloading a function that uses the
|
|
||||||
frame pointer. In this case, DESTINATION_REGS won't contain any
|
|
||||||
spillable registers, so the first alternative can't be used.
|
|
||||||
|
|
||||||
- -fno-omit-frame-pointer means that the frame pointer will
|
|
||||||
always be in use. It's therefore better to map 'd' to NO_REGS
|
|
||||||
before reload so that register allocator will pick the second
|
|
||||||
alternative.
|
|
||||||
|
|
||||||
- we would like 'D' to be be NO_REGS when the frame pointer isn't
|
|
||||||
live, but we the frame pointer may turn out to be needed after
|
|
||||||
we start reload, and then we may have already decided we don't
|
|
||||||
have a choice, so we can't do that. Forcing the register
|
|
||||||
allocator to use er6 if possible might produce better code for
|
|
||||||
small functions: it's more efficient to save and restore er6 in
|
|
||||||
the prologue & epilogue than to do it in a define_split.
|
|
||||||
Hopefully disparaging 'D' will have a similar effect, without
|
|
||||||
forcing a reload failure if the frame pointer is found to be
|
|
||||||
needed too late. */
|
|
||||||
|
|
||||||
enum reg_class
|
|
||||||
h8300_reg_class_from_letter (int c)
|
|
||||||
{
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case 'a':
|
|
||||||
return MAC_REGS;
|
|
||||||
|
|
||||||
case 'c':
|
|
||||||
return COUNTER_REGS;
|
|
||||||
|
|
||||||
case 'd':
|
|
||||||
if (!flag_omit_frame_pointer && !reload_completed)
|
|
||||||
return NO_REGS;
|
|
||||||
if (frame_pointer_needed && reload_in_progress)
|
|
||||||
return NO_REGS;
|
|
||||||
return DESTINATION_REGS;
|
|
||||||
|
|
||||||
case 'D':
|
|
||||||
/* The meaning of a constraint shouldn't change dynamically, so
|
|
||||||
we can't make this NO_REGS. */
|
|
||||||
return GENERAL_REGS;
|
|
||||||
|
|
||||||
case 'f':
|
|
||||||
return SOURCE_REGS;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return NO_REGS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the byte register name for a register rtx X. B should be 0
|
/* Return the byte register name for a register rtx X. B should be 0
|
||||||
if you want a lower byte register. B should be 1 if you want an
|
if you want a lower byte register. B should be 1 if you want an
|
||||||
upper byte register. */
|
upper byte register. */
|
||||||
@ -2827,7 +2763,7 @@ compute_mov_length (rtx *operands)
|
|||||||
if (REG_P (src))
|
if (REG_P (src))
|
||||||
return 4;
|
return 4;
|
||||||
|
|
||||||
if (CONST_DOUBLE_OK_FOR_LETTER_P (src, 'G'))
|
if (satisfies_constraint_G (src))
|
||||||
return 4;
|
return 4;
|
||||||
|
|
||||||
return 8;
|
return 8;
|
||||||
@ -2947,7 +2883,7 @@ compute_mov_length (rtx *operands)
|
|||||||
if (REG_P (src))
|
if (REG_P (src))
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
if (CONST_DOUBLE_OK_FOR_LETTER_P (src, 'G'))
|
if (satisfies_constraint_G (src))
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
return 6;
|
return 6;
|
||||||
@ -5186,7 +5122,7 @@ fix_bit_operand (rtx *operands, enum rtx_code code)
|
|||||||
{
|
{
|
||||||
/* OK to have a memory dest. */
|
/* OK to have a memory dest. */
|
||||||
if (GET_CODE (operands[0]) == MEM
|
if (GET_CODE (operands[0]) == MEM
|
||||||
&& !OK_FOR_U (operands[0]))
|
&& !satisfies_constraint_U (operands[0]))
|
||||||
{
|
{
|
||||||
rtx mem = gen_rtx_MEM (GET_MODE (operands[0]),
|
rtx mem = gen_rtx_MEM (GET_MODE (operands[0]),
|
||||||
copy_to_mode_reg (Pmode,
|
copy_to_mode_reg (Pmode,
|
||||||
@ -5196,7 +5132,7 @@ fix_bit_operand (rtx *operands, enum rtx_code code)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (GET_CODE (operands[1]) == MEM
|
if (GET_CODE (operands[1]) == MEM
|
||||||
&& !OK_FOR_U (operands[1]))
|
&& !satisfies_constraint_U (operands[1]))
|
||||||
{
|
{
|
||||||
rtx mem = gen_rtx_MEM (GET_MODE (operands[1]),
|
rtx mem = gen_rtx_MEM (GET_MODE (operands[1]),
|
||||||
copy_to_mode_reg (Pmode,
|
copy_to_mode_reg (Pmode,
|
||||||
|
@ -357,76 +357,6 @@ enum reg_class {
|
|||||||
#define INDEX_REG_CLASS (TARGET_H8300SX ? GENERAL_REGS : NO_REGS)
|
#define INDEX_REG_CLASS (TARGET_H8300SX ? GENERAL_REGS : NO_REGS)
|
||||||
#define BASE_REG_CLASS GENERAL_REGS
|
#define BASE_REG_CLASS GENERAL_REGS
|
||||||
|
|
||||||
/* Get reg_class from a letter such as appears in the machine description.
|
|
||||||
|
|
||||||
'a' is the MAC register. */
|
|
||||||
|
|
||||||
#define REG_CLASS_FROM_LETTER(C) (h8300_reg_class_from_letter (C))
|
|
||||||
|
|
||||||
/* 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.
|
|
||||||
This macro defines what the ranges are.
|
|
||||||
C is the letter, and VALUE is a constant value.
|
|
||||||
Return 1 if VALUE is in the range specified by C. */
|
|
||||||
|
|
||||||
#define CONST_OK_FOR_I(VALUE) ((VALUE) == 0)
|
|
||||||
#define CONST_OK_FOR_J(VALUE) (((VALUE) & 0xff) == 0)
|
|
||||||
#define CONST_OK_FOR_L(VALUE) \
|
|
||||||
(TARGET_H8300H || TARGET_H8300S \
|
|
||||||
? (VALUE) == 1 || (VALUE) == 2 || (VALUE) == 4 \
|
|
||||||
: (VALUE) == 1 || (VALUE) == 2)
|
|
||||||
#define CONST_OK_FOR_M(VALUE) \
|
|
||||||
((VALUE) == 1 || (VALUE) == 2)
|
|
||||||
#define CONST_OK_FOR_N(VALUE) \
|
|
||||||
(TARGET_H8300H || TARGET_H8300S \
|
|
||||||
? (VALUE) == -1 || (VALUE) == -2 || (VALUE) == -4 \
|
|
||||||
: (VALUE) == -1 || (VALUE) == -2)
|
|
||||||
#define CONST_OK_FOR_O(VALUE) \
|
|
||||||
((VALUE) == -1 || (VALUE) == -2)
|
|
||||||
|
|
||||||
/* Multi-letter constraints for constant are always started with P
|
|
||||||
(just because it was the only letter in the range left. New
|
|
||||||
constraints for constants should be added here. */
|
|
||||||
#define CONST_OK_FOR_Ppositive(VALUE, NBITS) \
|
|
||||||
((VALUE) > 0 && (VALUE) < (1 << (NBITS)))
|
|
||||||
#define CONST_OK_FOR_Pnegative(VALUE, NBITS) \
|
|
||||||
((VALUE) < 0 && (VALUE) > -(1 << (NBITS)))
|
|
||||||
#define CONST_OK_FOR_P(VALUE, STR) \
|
|
||||||
((STR)[1] >= '1' && (STR)[1] <= '9' && (STR)[2] == '<' \
|
|
||||||
? (((STR)[3] == '0' || ((STR)[3] == 'X' && TARGET_H8300SX)) \
|
|
||||||
&& CONST_OK_FOR_Pnegative ((VALUE), (STR)[1] - '0')) \
|
|
||||||
: ((STR)[1] >= '1' && (STR)[1] <= '9' && (STR)[2] == '>') \
|
|
||||||
? (((STR)[3] == '0' || ((STR)[3] == 'X' && TARGET_H8300SX)) \
|
|
||||||
&& CONST_OK_FOR_Ppositive ((VALUE), (STR)[1] - '0')) \
|
|
||||||
: 0)
|
|
||||||
#define CONSTRAINT_LEN_FOR_P(STR) \
|
|
||||||
((((STR)[1] >= '1' && (STR)[1] <= '9') \
|
|
||||||
&& ((STR)[2] == '<' || (STR)[2] == '>') \
|
|
||||||
&& ((STR)[3] == 'X' || (STR)[3] == '0')) ? 4 \
|
|
||||||
: 0)
|
|
||||||
|
|
||||||
#define CONST_OK_FOR_CONSTRAINT_P(VALUE, C, STR) \
|
|
||||||
((C) == 'P' ? CONST_OK_FOR_P ((VALUE), (STR)) \
|
|
||||||
: CONST_OK_FOR_LETTER_P ((VALUE), (C)))
|
|
||||||
|
|
||||||
#define CONST_OK_FOR_LETTER_P(VALUE, C) \
|
|
||||||
((C) == 'I' ? CONST_OK_FOR_I (VALUE) : \
|
|
||||||
(C) == 'J' ? CONST_OK_FOR_J (VALUE) : \
|
|
||||||
(C) == 'L' ? CONST_OK_FOR_L (VALUE) : \
|
|
||||||
(C) == 'M' ? CONST_OK_FOR_M (VALUE) : \
|
|
||||||
(C) == 'N' ? CONST_OK_FOR_N (VALUE) : \
|
|
||||||
(C) == 'O' ? CONST_OK_FOR_O (VALUE) : \
|
|
||||||
0)
|
|
||||||
|
|
||||||
/* Similar, but for floating constants, and defining letters G and H.
|
|
||||||
Here VALUE is the CONST_DOUBLE rtx itself.
|
|
||||||
|
|
||||||
`G' is a floating-point zero. */
|
|
||||||
|
|
||||||
#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
|
|
||||||
((C) == 'G' ? (VALUE) == CONST0_RTX (SFmode) \
|
|
||||||
: 0)
|
|
||||||
|
|
||||||
/* Return the maximum number of consecutive registers
|
/* Return the maximum number of consecutive registers
|
||||||
needed to represent mode MODE in a register of class CLASS. */
|
needed to represent mode MODE in a register of class CLASS. */
|
||||||
|
|
||||||
@ -645,122 +575,6 @@ struct cum_arg
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Extra constraints. */
|
|
||||||
|
|
||||||
#define OK_FOR_Q(OP) \
|
|
||||||
(TARGET_H8300SX && memory_operand ((OP), VOIDmode))
|
|
||||||
|
|
||||||
#define OK_FOR_R(OP) \
|
|
||||||
(GET_CODE (OP) == CONST_INT \
|
|
||||||
? !h8300_shift_needs_scratch_p (INTVAL (OP), QImode) \
|
|
||||||
: 0)
|
|
||||||
|
|
||||||
#define OK_FOR_S(OP) \
|
|
||||||
(GET_CODE (OP) == CONST_INT \
|
|
||||||
? !h8300_shift_needs_scratch_p (INTVAL (OP), HImode) \
|
|
||||||
: 0)
|
|
||||||
|
|
||||||
#define OK_FOR_T(OP) \
|
|
||||||
(GET_CODE (OP) == CONST_INT \
|
|
||||||
? !h8300_shift_needs_scratch_p (INTVAL (OP), SImode) \
|
|
||||||
: 0)
|
|
||||||
|
|
||||||
/* 'U' if valid for a bset destination;
|
|
||||||
i.e. a register, register indirect, or the eightbit memory region
|
|
||||||
(a SYMBOL_REF with an SYMBOL_REF_FLAG set).
|
|
||||||
|
|
||||||
On the H8S 'U' can also be a 16bit or 32bit absolute. */
|
|
||||||
#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))) \
|
|
||||||
|| (GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == SYMBOL_REF \
|
|
||||||
&& TARGET_H8300S) \
|
|
||||||
|| (GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == CONST \
|
|
||||||
&& GET_CODE (XEXP (XEXP (OP, 0), 0)) == PLUS \
|
|
||||||
&& GET_CODE (XEXP (XEXP (XEXP (OP, 0), 0), 0)) == SYMBOL_REF \
|
|
||||||
&& GET_CODE (XEXP (XEXP (XEXP (OP, 0), 0), 1)) == CONST_INT \
|
|
||||||
&& (TARGET_H8300S \
|
|
||||||
|| SYMBOL_REF_FLAG (XEXP (XEXP (XEXP (OP, 0), 0), 0)))) \
|
|
||||||
|| (GET_CODE (OP) == MEM \
|
|
||||||
&& h8300_eightbit_constant_address_p (XEXP (OP, 0))) \
|
|
||||||
|| (GET_CODE (OP) == MEM && (TARGET_H8300S || TARGET_H8300SX) \
|
|
||||||
&& GET_CODE (XEXP (OP, 0)) == CONST_INT))
|
|
||||||
|
|
||||||
/* Multi-letter constraints starting with W are to be used for
|
|
||||||
operands that require a memory operand, i.e,. that are never used
|
|
||||||
along with register constraints (see EXTRA_MEMORY_CONSTRAINTS). */
|
|
||||||
|
|
||||||
#define OK_FOR_WU(OP) \
|
|
||||||
(GET_CODE (OP) == MEM && OK_FOR_U (OP))
|
|
||||||
|
|
||||||
#define OK_FOR_W(OP, STR) \
|
|
||||||
((STR)[1] == 'U' ? OK_FOR_WU (OP) \
|
|
||||||
: 0)
|
|
||||||
|
|
||||||
#define CONSTRAINT_LEN_FOR_W(STR) \
|
|
||||||
((STR)[1] == 'U' ? 2 \
|
|
||||||
: 0)
|
|
||||||
|
|
||||||
/* Multi-letter constraints starting with Y are to be used for operands
|
|
||||||
that are constant immediates and have single 1 or 0 in their binary
|
|
||||||
representation. */
|
|
||||||
|
|
||||||
#define OK_FOR_Y2(OP) \
|
|
||||||
((GET_CODE (OP) == CONST_INT) && (exact_log2 (INTVAL (OP) & 0xff) != -1))
|
|
||||||
|
|
||||||
#define OK_FOR_Y0(OP) \
|
|
||||||
((GET_CODE (OP) == CONST_INT) && (exact_log2 (~INTVAL (OP) & 0xff) != -1))
|
|
||||||
|
|
||||||
#define OK_FOR_Y(OP, STR) \
|
|
||||||
((STR)[1] == '2' ? OK_FOR_Y2 (OP) \
|
|
||||||
: (STR)[1] == '0' ? OK_FOR_Y0 (OP) \
|
|
||||||
: 0)
|
|
||||||
|
|
||||||
#define CONSTRAINT_LEN_FOR_Y(STR) \
|
|
||||||
((STR)[1] == '2' ? 2 \
|
|
||||||
: (STR)[1] == '0' ? 2 \
|
|
||||||
: 0)
|
|
||||||
|
|
||||||
#define OK_FOR_Z(OP) \
|
|
||||||
(TARGET_H8300SX \
|
|
||||||
&& GET_CODE (OP) == MEM \
|
|
||||||
&& CONSTANT_P (XEXP ((OP), 0)))
|
|
||||||
|
|
||||||
#define EXTRA_CONSTRAINT_STR(OP, C, STR) \
|
|
||||||
((C) == 'Q' ? OK_FOR_Q (OP) : \
|
|
||||||
(C) == 'R' ? OK_FOR_R (OP) : \
|
|
||||||
(C) == 'S' ? OK_FOR_S (OP) : \
|
|
||||||
(C) == 'T' ? OK_FOR_T (OP) : \
|
|
||||||
(C) == 'U' ? OK_FOR_U (OP) : \
|
|
||||||
(C) == 'W' ? OK_FOR_W ((OP), (STR)) : \
|
|
||||||
(C) == 'Y' ? OK_FOR_Y ((OP), (STR)) : \
|
|
||||||
(C) == 'Z' ? OK_FOR_Z (OP) : \
|
|
||||||
0)
|
|
||||||
|
|
||||||
#define CONSTRAINT_LEN(C, STR) \
|
|
||||||
((C) == 'P' ? CONSTRAINT_LEN_FOR_P (STR) \
|
|
||||||
: (C) == 'W' ? CONSTRAINT_LEN_FOR_W (STR) \
|
|
||||||
: (C) == 'Y' ? CONSTRAINT_LEN_FOR_Y (STR) \
|
|
||||||
: DEFAULT_CONSTRAINT_LEN ((C), (STR)))
|
|
||||||
|
|
||||||
/* Experiments suggest that it's better not add 'Q' or 'U' here. No
|
|
||||||
patterns need it for correctness (no patterns use 'Q' and 'U'
|
|
||||||
without also providing a register alternative). And defining it
|
|
||||||
will mean that a spilled pseudo could be replaced by its frame
|
|
||||||
location in several consecutive insns.
|
|
||||||
|
|
||||||
Instead, it seems to be better to force pseudos to be reloaded
|
|
||||||
into registers and then use peepholes to recombine insns when
|
|
||||||
beneficial.
|
|
||||||
|
|
||||||
Unfortunately, for WU (unlike plain U, that matches regs as well),
|
|
||||||
we must require a memory address. In fact, all multi-letter
|
|
||||||
constraints started with W are supposed to have this property, so
|
|
||||||
we just test for W here. */
|
|
||||||
#define EXTRA_MEMORY_CONSTRAINT(C, STR) \
|
|
||||||
((C) == 'W')
|
|
||||||
|
|
||||||
|
|
||||||
/* Specify the machine mode that this machine uses
|
/* Specify the machine mode that this machine uses
|
||||||
for the index in the tablejump instruction. */
|
for the index in the tablejump instruction. */
|
||||||
|
@ -177,6 +177,7 @@
|
|||||||
(const_int 14)))])
|
(const_int 14)))])
|
||||||
|
|
||||||
(include "predicates.md")
|
(include "predicates.md")
|
||||||
|
(include "constraints.md")
|
||||||
|
|
||||||
;; ----------------------------------------------------------------------
|
;; ----------------------------------------------------------------------
|
||||||
;; MOVE INSTRUCTIONS
|
;; MOVE INSTRUCTIONS
|
||||||
@ -995,7 +996,7 @@
|
|||||||
btst\\t%Z1,%Y0
|
btst\\t%Z1,%Y0
|
||||||
#"
|
#"
|
||||||
"&& reload_completed
|
"&& reload_completed
|
||||||
&& !OK_FOR_U (operands[0])"
|
&& !satisfies_constraint_U (operands[0])"
|
||||||
[(set (match_dup 2)
|
[(set (match_dup 2)
|
||||||
(match_dup 0))
|
(match_dup 0))
|
||||||
(parallel [(set (cc0) (compare (zero_extract:SI (match_dup 2)
|
(parallel [(set (cc0) (compare (zero_extract:SI (match_dup 2)
|
||||||
@ -1065,7 +1066,7 @@
|
|||||||
btst\\t%w1,%X0
|
btst\\t%w1,%X0
|
||||||
#"
|
#"
|
||||||
"&& reload_completed
|
"&& reload_completed
|
||||||
&& !OK_FOR_U (operands[0])"
|
&& !satisfies_constraint_U (operands[0])"
|
||||||
[(set (match_dup 2)
|
[(set (match_dup 2)
|
||||||
(match_dup 0))
|
(match_dup 0))
|
||||||
(parallel [(set (cc0) (compare (zero_extract:SI (zero_extend:SI (match_dup 2))
|
(parallel [(set (cc0) (compare (zero_extract:SI (zero_extend:SI (match_dup 2))
|
||||||
@ -4867,9 +4868,9 @@
|
|||||||
(match_operand:HI 2 "register_operand" "")))]
|
(match_operand:HI 2 "register_operand" "")))]
|
||||||
"REG_P (operands[0]) && REG_P (operands[2])
|
"REG_P (operands[0]) && REG_P (operands[2])
|
||||||
&& REGNO (operands[0]) != REGNO (operands[2])
|
&& REGNO (operands[0]) != REGNO (operands[2])
|
||||||
&& (CONST_OK_FOR_J (INTVAL (operands[1]))
|
&& (satisfies_constraint_J (operands[1])
|
||||||
|| CONST_OK_FOR_L (INTVAL (operands[1]))
|
|| satisfies_constraint_L (operands[1])
|
||||||
|| CONST_OK_FOR_N (INTVAL (operands[1])))"
|
|| satisfies_constraint_N (operands[1]))"
|
||||||
[(set (match_dup 0)
|
[(set (match_dup 0)
|
||||||
(match_dup 2))
|
(match_dup 2))
|
||||||
(set (match_dup 0)
|
(set (match_dup 0)
|
||||||
@ -4897,8 +4898,8 @@
|
|||||||
"(TARGET_H8300H || TARGET_H8300S)
|
"(TARGET_H8300H || TARGET_H8300S)
|
||||||
&& REG_P (operands[0]) && REG_P (operands[2])
|
&& REG_P (operands[0]) && REG_P (operands[2])
|
||||||
&& REGNO (operands[0]) != REGNO (operands[2])
|
&& REGNO (operands[0]) != REGNO (operands[2])
|
||||||
&& (CONST_OK_FOR_L (INTVAL (operands[1]))
|
&& (satisfies_constraint_L (operands[1])
|
||||||
|| CONST_OK_FOR_N (INTVAL (operands[1])))"
|
|| satisfies_constraint_N (operands[1]))"
|
||||||
[(set (match_dup 0)
|
[(set (match_dup 0)
|
||||||
(match_dup 2))
|
(match_dup 2))
|
||||||
(set (match_dup 0)
|
(set (match_dup 0)
|
||||||
@ -4926,8 +4927,8 @@
|
|||||||
"(TARGET_H8300H || TARGET_H8300S)
|
"(TARGET_H8300H || TARGET_H8300S)
|
||||||
&& REG_P (operands[0]) && REG_P (operands[1])
|
&& REG_P (operands[0]) && REG_P (operands[1])
|
||||||
&& REGNO (operands[0]) != REGNO (operands[1])
|
&& REGNO (operands[0]) != REGNO (operands[1])
|
||||||
&& !CONST_OK_FOR_L (INTVAL (operands[2]))
|
&& !satisfies_constraint_L (operands[2])
|
||||||
&& !CONST_OK_FOR_N (INTVAL (operands[2]))
|
&& !satisfies_constraint_N (operands[2])
|
||||||
&& ((INTVAL (operands[2]) & 0xff) == INTVAL (operands[2])
|
&& ((INTVAL (operands[2]) & 0xff) == INTVAL (operands[2])
|
||||||
|| (INTVAL (operands[2]) & 0xff00) == INTVAL (operands[2])
|
|| (INTVAL (operands[2]) & 0xff00) == INTVAL (operands[2])
|
||||||
|| INTVAL (operands[2]) == 0xffff
|
|| INTVAL (operands[2]) == 0xffff
|
||||||
|
@ -326,7 +326,7 @@
|
|||||||
{
|
{
|
||||||
/* We can accept any nonimmediate operand, except that MEM operands must
|
/* We can accept any nonimmediate operand, except that MEM operands must
|
||||||
be limited to those that use addresses valid for the 'U' constraint. */
|
be limited to those that use addresses valid for the 'U' constraint. */
|
||||||
if (!nonimmediate_operand (op, mode) && !OK_FOR_U (op))
|
if (!nonimmediate_operand (op, mode) && !satisfies_constraint_U (op))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* H8SX accepts pretty much anything here. */
|
/* H8SX accepts pretty much anything here. */
|
||||||
@ -344,7 +344,7 @@
|
|||||||
if (GET_CODE (op) == SUBREG)
|
if (GET_CODE (op) == SUBREG)
|
||||||
return 1;
|
return 1;
|
||||||
return (GET_CODE (op) == MEM
|
return (GET_CODE (op) == MEM
|
||||||
&& OK_FOR_U (op));
|
&& satisfies_constraint_U (op));
|
||||||
})
|
})
|
||||||
|
|
||||||
;; Return nonzero if OP is a MEM suitable for bit manipulation insns.
|
;; Return nonzero if OP is a MEM suitable for bit manipulation insns.
|
||||||
@ -353,7 +353,7 @@
|
|||||||
(match_code "mem")
|
(match_code "mem")
|
||||||
{
|
{
|
||||||
return (GET_CODE (op) == MEM
|
return (GET_CODE (op) == MEM
|
||||||
&& OK_FOR_U (op));
|
&& satisfies_constraint_U (op));
|
||||||
})
|
})
|
||||||
|
|
||||||
;; Return nonzero if OP is indirect register or constant memory
|
;; Return nonzero if OP is indirect register or constant memory
|
||||||
@ -416,12 +416,9 @@
|
|||||||
;; Return nonzero if X is a constant suitable for inc/dec.
|
;; Return nonzero if X is a constant suitable for inc/dec.
|
||||||
|
|
||||||
(define_predicate "incdec_operand"
|
(define_predicate "incdec_operand"
|
||||||
(match_code "const_int")
|
(and (match_code "const_int")
|
||||||
{
|
(ior (match_test "satisfies_constraint_M (op)")
|
||||||
return (GET_CODE (op) == CONST_INT
|
(match_test "satisfies_constraint_O (op)"))))
|
||||||
&& (CONST_OK_FOR_M (INTVAL (op))
|
|
||||||
|| CONST_OK_FOR_O (INTVAL (op))));
|
|
||||||
})
|
|
||||||
|
|
||||||
;; Recognize valid operators for bit instructions.
|
;; Recognize valid operators for bit instructions.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user