GCC Middle and Back End API Reference
genpreds.cc File Reference
#include "bconfig.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "errors.h"
#include "obstack.h"
#include "read-md.h"
#include "gensupport.h"
Include dependency graph for genpreds.cc:

Data Structures

class  constraint_data
 

Macros

#define NO_MODE_TEST(EXP)   RTX_FLAG (EXP, volatil)
 
#define FOR_ALL_CONSTRAINTS(iter_)    for (iter_ = first_constraint; iter_; iter_ = iter_->next_textual)
 

Functions

static bool validate_exp (rtx exp, const char *name, file_location loc)
 
static void process_define_predicate (md_rtx_info *info)
 
static void write_predicate_subfunction (struct pred_data *p)
 
static bool needs_variable (rtx exp, const char *var)
 
static void mark_mode_tests (rtx exp)
 
static bool generate_switch_p (rtx exp)
 
static void add_mode_tests (struct pred_data *p)
 
static void write_extract_subexp (const char *path)
 
static void write_match_code (const char *path, const char *codes)
 
static void write_predicate_expr (rtx exp)
 
static void write_match_code_switch (rtx exp)
 
static void write_predicate_stmts (rtx exp)
 
static void write_one_predicate_function (struct pred_data *p)
 
static const char * mangle (const char *name)
 
static void add_constraint (const char *name, const char *regclass, rtx exp, bool is_memory, bool is_special_memory, bool is_relaxed_memory, bool is_address, file_location loc, const char *filter=nullptr)
 
static void process_define_constraint (md_rtx_info *info)
 
static void process_define_register_constraint (md_rtx_info *info)
 
static void choose_enum_order (void)
 
static void write_enum_constraint_num (void)
 
static void write_lookup_constraint_1 (void)
 
static void write_lookup_constraint_array (void)
 
static void write_insn_constraint_len (void)
 
static void write_reg_class_for_constraint_1 (void)
 
static void write_tm_constrs_h (void)
 
static void write_constraint_satisfied_p_array (void)
 
static void write_insn_const_int_ok_for_constraint (void)
 
static void write_init_reg_class_start_regs ()
 
static void write_range_function (const char *name, unsigned int start, unsigned int end)
 
static void write_allows_reg_mem_function (void)
 
static void print_type_tree (const vec< std::pair< unsigned int, const char * > > &vec, unsigned int start, unsigned int end, const char *fallback, unsigned int indent)
 
static void write_get_register_filter ()
 
static void write_get_register_filter_id ()
 
static void write_tm_preds_h (void)
 
static void write_insn_preds_c (void)
 
static bool parse_option (const char *opt)
 
int main (int argc, const char **argv)
 

Variables

static char general_mem [] = { TARGET_MEM_CONSTRAINT, 0 }
 
static class constraint_dataconstraints_by_letter_table [1<< CHAR_BIT]
 
static class constraint_datafirst_constraint
 
static class constraint_data ** last_constraint_ptr = &first_constraint
 
static const char generic_constraint_letters [] = "g"
 
static const char const_int_constraints [] = "IJKLMNOP"
 
static const char const_dbl_constraints [] = "GH"
 
static unsigned int constraint_max_namelen
 
static bool have_register_constraints
 
static bool have_memory_constraints
 
static bool have_special_memory_constraints
 
static bool have_relaxed_memory_constraints
 
static bool have_address_constraints
 
static bool have_extra_constraints
 
static bool have_const_int_constraints
 
static unsigned int num_constraints
 
static const constraint_data ** enum_order
 
static unsigned int register_start
 
static unsigned int register_end
 
static unsigned int satisfied_start
 
static unsigned int const_int_start
 
static unsigned int const_int_end
 
static unsigned int memory_start
 
static unsigned int memory_end
 
static unsigned int special_memory_start
 
static unsigned int special_memory_end
 
static unsigned int relaxed_memory_start
 
static unsigned int relaxed_memory_end
 
static unsigned int address_start
 
static unsigned int address_end
 
static unsigned int maybe_allows_none_start
 
static unsigned int maybe_allows_none_end
 
static unsigned int maybe_allows_reg_start
 
static unsigned int maybe_allows_reg_end
 
static unsigned int maybe_allows_mem_start
 
static unsigned int maybe_allows_mem_end
 
static bool gen_header
 
static bool gen_constrs
 

Macro Definition Documentation

◆ FOR_ALL_CONSTRAINTS

◆ NO_MODE_TEST

#define NO_MODE_TEST ( EXP)    RTX_FLAG (EXP, volatil)
Given an RTL expression EXP, find all subexpressions which we may
  assume to perform mode tests.  Normal MATCH_OPERAND does;
  MATCH_CODE doesn't as such (although certain codes always have
  VOIDmode); and we have to assume that MATCH_TEST does not.
  These combine in almost-boolean fashion - the only exception is
  that (not X) must be assumed not to perform a mode test, whether
  or not X does.

  The mark is the RTL /v flag, which is true for subexpressions which
  do *not* perform mode tests.

Referenced by add_mode_tests(), and mark_mode_tests().

Function Documentation

◆ add_constraint()

static void add_constraint ( const char * name,
const char * regclass,
rtx exp,
bool is_memory,
bool is_special_memory,
bool is_relaxed_memory,
bool is_address,
file_location loc,
const char * filter = nullptr )
static
Add one constraint, of any sort, to the tables.  NAME is its name; REGCLASS
is the register class, if any; EXP is the expression to test, if any;
IS_MEMORY, IS_SPECIAL_MEMORY, IS_RELAXED_MEMORY and IS_ADDRESS indicate
memory, special memory, and address constraints, respectively; LOC is the .md
file location; FILTER is the filter condition for a register constraint,
or null if none.

Not all combinations of arguments are valid; most importantly, REGCLASS is
mutually exclusive with EXP, and
IS_MEMORY/IS_SPECIAL_MEMORY/IS_RELAXED_MEMORY/IS_ADDRESS are only meaningful
for constraints with EXP.

This function enforces all syntactic and semantic rules about what
constraints can be defined.   

References constraint_data::c_name, compute_test_codes(), const_dbl_constraints, const_int_constraints, constraint_max_namelen, constraints_by_letter_table, error_at(), constraint_data::exp, exp(), constraint_data::filter, general_mem, generic_constraint_letters, GET_CODE, GET_RTX_NAME, have_address_constraints, have_const_int_constraints, have_extra_constraints, have_memory_constraints, have_register_constraints, have_relaxed_memory_constraints, have_special_memory_constraints, constraint_data::is_address, constraint_data::is_const_dbl, constraint_data::is_const_int, constraint_data::is_extra, constraint_data::is_memory, constraint_data::is_register, constraint_data::is_relaxed_memory, constraint_data::is_special_memory, last_constraint_ptr, constraint_data::loc, mangle(), MAX, constraint_data::maybe_allows_mem, constraint_data::maybe_allows_reg, message_at(), constraint_data::name, constraint_data::namelen, constraint_data::next_textual, constraint_data::next_this_letter, num_constraints, NUM_RTX_CODE, constraint_data::regclass, regclass(), rtl_obstack, validate_exp(), XEXP, and XSTR.

Referenced by process_define_constraint(), and process_define_register_constraint().

◆ add_mode_tests()

static void add_mode_tests ( struct pred_data * p)
static
Given a predicate, work out where in its RTL expression to add
tests for proper modes.  Special predicates do not get any such
tests.  We try to avoid adding tests when we don't have to; in
particular, other normal predicates can be counted on to do it for
us.   

References pred_data::codes, pred_data::exp, gcc_assert, generate_switch_p(), GET_CODE, i, mark_mode_tests(), NO_MODE_TEST, NUM_RTX_CODE, rtx_alloc(), pred_data::special, TARGET_SUPPORTS_WIDE_INT, XEXP, and XSTR.

Referenced by write_one_predicate_function().

◆ choose_enum_order()

◆ generate_switch_p()

static bool generate_switch_p ( rtx exp)
static
Determine whether the expression EXP is a MATCH_CODE that should
be written as a switch statement.   

References exp(), GET_CODE, and XSTR.

Referenced by add_mode_tests(), and write_predicate_stmts().

◆ main()

◆ mangle()

static const char * mangle ( const char * name)
static
Convert NAME, which contains angle brackets and/or underscores, to
a string that can be used as part of a C identifier.  The string
comes from the rtl_obstack.   

References constraint_data::name, and rtl_obstack.

Referenced by add_constraint().

◆ mark_mode_tests()

static void mark_mode_tests ( rtx exp)
static

◆ needs_variable()

static bool needs_variable ( rtx exp,
const char * var )
static
Given a predicate expression EXP, from form NAME, determine whether
it refers to the variable given as VAR.   

References exp(), gcc_unreachable, GET_CODE, GET_MODE, needs_variable(), XEXP, and XSTR.

Referenced by needs_variable(), and write_tm_constrs_h().

◆ parse_option()

static bool parse_option ( const char * opt)
static

References gen_constrs, and gen_header.

Referenced by main().

◆ print_type_tree()

static void print_type_tree ( const vec< std::pair< unsigned int, const char * > > & vec,
unsigned int start,
unsigned int end,
const char * fallback,
unsigned int indent )
static
VEC is a list of key/value pairs, with the keys being lower bounds
of a range.  Output a decision tree that handles the keys covered by
[VEC[START], VEC[END]), returning FALLBACK for keys lower then VEC[START]'s.
INDENT is the number of spaces to indent the code.   

References constraint_data::c_name, end(), enum_order, and print_type_tree().

Referenced by print_type_tree(), and write_tm_preds_h().

◆ process_define_constraint()

static void process_define_constraint ( md_rtx_info * info)
static
Process a DEFINE_CONSTRAINT, DEFINE_MEMORY_CONSTRAINT,
DEFINE_SPECIAL_MEMORY_CONSTRAINT, DEFINE_RELAXED_MEMORY_CONSTRAINT, or
DEFINE_ADDRESS_CONSTRAINT expression, C.   

References add_constraint(), md_rtx_info::def, GET_CODE, md_rtx_info::loc, XEXP, and XSTR.

Referenced by main().

◆ process_define_predicate()

static void process_define_predicate ( md_rtx_info * info)
static
Predicates are defined with (define_predicate) or
(define_special_predicate) expressions in the machine description.   

References md_rtx_info::def, md_rtx_info::loc, validate_exp(), XEXP, and XSTR.

Referenced by main().

◆ process_define_register_constraint()

static void process_define_register_constraint ( md_rtx_info * info)
static
Process a DEFINE_REGISTER_CONSTRAINT expression, C.   

References add_constraint(), md_rtx_info::def, md_rtx_info::loc, and XSTR.

Referenced by main().

◆ validate_exp()

static bool validate_exp ( rtx exp,
const char * name,
file_location loc )
static
Given a predicate expression EXP, from form NAME at location LOC,
verify that it does not contain any RTL constructs which are not
valid in predicate definitions.  Returns true if EXP is
INvalid; issues error messages, caller need not.   

References error_at(), exp(), gcc_fallthrough, GET_CODE, GET_RTX_NAME, message_at(), validate_exp(), XEXP, and XSTR.

Referenced by add_constraint(), process_define_predicate(), and validate_exp().

◆ write_allows_reg_mem_function()

static void write_allows_reg_mem_function ( void )
static

◆ write_constraint_satisfied_p_array()

static void write_constraint_satisfied_p_array ( void )
static
Write out the wrapper function, constraint_satisfied_p, that maps
a CONSTRAINT_xxx constant to one of the predicate functions generated
above.   

References constraint_data::c_name, enum_order, i, num_constraints, and satisfied_start.

Referenced by write_insn_preds_c().

◆ write_enum_constraint_num()

static void write_enum_constraint_num ( void )
static
Write out an enumeration with one entry per machine-specific
constraint.   

References constraint_data::c_name, enum_order, i, and num_constraints.

Referenced by write_tm_preds_h().

◆ write_extract_subexp()

static void write_extract_subexp ( const char * path)
static
PATH is a string describing a path from the root of an RTL
expression to an inner subexpression to be tested.  Output
code which computes the subexpression from the variable
holding the root of the expression.   

References gcc_unreachable, and i.

Referenced by write_match_code(), and write_match_code_switch().

◆ write_get_register_filter()

static void write_get_register_filter ( )
static
Print the get_register_filter function, which returns a pointer
to the start register filter for a given constraint, or null if none.   

References constraint_data::c_name, constraint_data::filter, FOR_ALL_CONSTRAINTS, get_register_filter_id(), constraint_data::is_register, and register_filters.

Referenced by write_tm_preds_h().

◆ write_get_register_filter_id()

static void write_get_register_filter_id ( )
static
Print the get_register_filter_id function, which returns the index
of the given constraint's register filter in
this_target_constraints->register_filters, or -1 if none.   

References constraint_data::c_name, constraint_data::filter, FOR_ALL_CONSTRAINTS, get_register_filter_id(), constraint_data::is_register, and register_filters.

Referenced by write_tm_preds_h().

◆ write_init_reg_class_start_regs()

static void write_init_reg_class_start_regs ( )
static
Print the init_reg_class_start_regs function, which initializes
this_target_constraints->register_filters from the C conditions
in the define_register_constraints.   

References i, md_reader::print_c_condition(), register_filters, and rtx_reader_ptr.

Referenced by write_insn_preds_c().

◆ write_insn_const_int_ok_for_constraint()

static void write_insn_const_int_ok_for_constraint ( void )
static
Write out the function which computes whether a given value matches
a given CONST_INT constraint.  This doesn't just forward to
constraint_satisfied_p because caller passes the INTVAL, not the RTX.   

References constraint_data::c_name, constraint_data::exp, FOR_ALL_CONSTRAINTS, constraint_data::is_const_int, write_predicate_expr(), and XEXP.

Referenced by write_insn_preds_c().

◆ write_insn_constraint_len()

static void write_insn_constraint_len ( void )
static
Write out a function which looks at a string and determines what
the constraint name length is.   

References constraints_by_letter_table, error(), fmt_size_t, HOST_SIZE_T_PRINT_UNSIGNED, i, constraint_data::namelen, and constraint_data::next_this_letter.

Referenced by write_tm_preds_h().

◆ write_insn_preds_c()

static void write_insn_preds_c ( void )
static
Write insn-preds.cc.
N.B. the list of headers to include was copied from genrecog; it
may not be ideal.

FUTURE: Write #line markers referring back to the machine
description.  (Can't practically do this now since we don't know
the line number of the C block - just the line number of the enclosing
expression.)   

References constraint_max_namelen, FOR_ALL_PREDICATES, md_reader::get_top_level_filename(), have_const_int_constraints, have_register_constraints, md_reader_ptr, progname, write_constraint_satisfied_p_array(), write_init_reg_class_start_regs(), write_insn_const_int_ok_for_constraint(), write_lookup_constraint_1(), write_lookup_constraint_array(), write_one_predicate_function(), and write_reg_class_for_constraint_1().

Referenced by main().

◆ write_lookup_constraint_1()

static void write_lookup_constraint_1 ( void )
static
Write out a function which looks at a string and determines what
constraint name, if any, it begins with.   

References constraint_data::c_name, constraints_by_letter_table, fmt_size_t, HOST_SIZE_T_PRINT_UNSIGNED, i, constraint_data::name, constraint_data::namelen, and constraint_data::next_this_letter.

Referenced by write_insn_preds_c().

◆ write_lookup_constraint_array()

static void write_lookup_constraint_array ( void )
static
Write out an array that maps single-letter characters to their
constraints (if that fits in a character) or 255 if lookup_constraint_1
must be called.   

References constraint_data::c_name, constraints_by_letter_table, i, and constraint_data::namelen.

Referenced by write_insn_preds_c().

◆ write_match_code()

static void write_match_code ( const char * path,
const char * codes )
static
CODES is a list of RTX codes.  Write out an expression which
determines whether the operand has one of those codes.   

References pred_data::codes, scan_comma_elt(), and write_extract_subexp().

Referenced by write_predicate_expr().

◆ write_match_code_switch()

static void write_match_code_switch ( rtx exp)
static
Write the MATCH_CODE expression EXP as a switch statement.   

References pred_data::codes, exp(), scan_comma_elt(), write_extract_subexp(), and XSTR.

Referenced by write_predicate_stmts().

◆ write_one_predicate_function()

static void write_one_predicate_function ( struct pred_data * p)
static
Given a predicate, write out a complete C function to compute it.   

References add_mode_tests(), pred_data::exp, pred_data::name, write_predicate_stmts(), and write_predicate_subfunction().

Referenced by write_insn_preds_c().

◆ write_predicate_expr()

static void write_predicate_expr ( rtx exp)
static
EXP is an RTL (sub)expression for a predicate.  Recursively
descend the expression and write out an equivalent C expression.   

References exp(), gcc_unreachable, GET_CODE, GET_MODE, mode_name, md_reader::print_c_condition(), rtx_reader_ptr, write_match_code(), write_predicate_expr(), XEXP, and XSTR.

Referenced by write_insn_const_int_ok_for_constraint(), write_predicate_expr(), and write_predicate_stmts().

◆ write_predicate_stmts()

static void write_predicate_stmts ( rtx exp)
static
Given a predicate expression EXP, write out a sequence of stmts
to evaluate it.  This is similar to write_predicate_expr but can
generate efficient switch statements.   

References exp(), generate_switch_p(), GET_CODE, write_match_code_switch(), write_predicate_expr(), and XEXP.

Referenced by write_one_predicate_function(), and write_tm_constrs_h().

◆ write_predicate_subfunction()

static void write_predicate_subfunction ( struct pred_data * p)
static
Given a predicate, if it has an embedded C block, write the block
out as a static inline subroutine, and augment the RTL test with a
match_test that calls that subroutine.  For instance,

    (define_predicate "basereg_operand"
      (match_operand 0 "register_operand")
    {
      if (GET_CODE (op) == SUBREG)
        op = SUBREG_REG (op);
      return REG_POINTER (op);
    })

becomes

    static inline bool basereg_operand_1(rtx op, machine_mode mode)
    {
      if (GET_CODE (op) == SUBREG)
        op = SUBREG_REG (op);
      return REG_POINTER (op);
    }

    (define_predicate "basereg_operand"
      (and (match_operand 0 "register_operand")
           (match_test "basereg_operand_1 (op, mode)")))

The only wart is that there's no way to insist on a { } string in
an RTL template, so we have to handle "" strings.   

References pred_data::c_block, pred_data::exp, pred_data::name, md_reader::print_md_ptr_loc(), rtl_obstack, rtx_alloc(), rtx_reader_ptr, XEXP, and XSTR.

Referenced by write_one_predicate_function().

◆ write_range_function()

static void write_range_function ( const char * name,
unsigned int start,
unsigned int end )
static
Write a definition for a function NAME that returns true if a given
constraint_num is in the range [START, END).   

References constraint_data::c_name, end(), enum_order, and constraint_data::name.

Referenced by write_tm_preds_h().

◆ write_reg_class_for_constraint_1()

static void write_reg_class_for_constraint_1 ( void )
static
Write out the function which computes the register class corresponding
to a register constraint.   

References constraint_data::c_name, FOR_ALL_CONSTRAINTS, constraint_data::is_register, and constraint_data::regclass.

Referenced by write_insn_preds_c().

◆ write_tm_constrs_h()

static void write_tm_constrs_h ( void )
static
Write out the functions which compute whether a given value matches
a given non-register constraint.   

References constraint_data::c_name, error(), constraint_data::exp, FOR_ALL_CONSTRAINTS, md_reader::get_top_level_filename(), constraint_data::is_register, md_reader_ptr, needs_variable(), progname, and write_predicate_stmts().

Referenced by main().

◆ write_tm_preds_h()

Variable Documentation

◆ address_end

unsigned int address_end
static

◆ address_start

unsigned int address_start
static

◆ const_dbl_constraints

const char const_dbl_constraints[] = "GH"
static
Machine-independent code expects that constraints with these
(initial) letters will allow only (a subset of all) CONST_DOUBLEs.   

Referenced by add_constraint().

◆ const_int_constraints

const char const_int_constraints[] = "IJKLMNOP"
static
Machine-independent code expects that constraints with these
(initial) letters will allow only (a subset of all) CONST_INTs.   

Referenced by add_constraint().

◆ const_int_end

unsigned int const_int_end
static

◆ const_int_start

unsigned int const_int_start
static

◆ constraint_max_namelen

unsigned int constraint_max_namelen
static
Summary data used to decide whether to output various functions and
macro definitions.   

Referenced by add_constraint(), write_insn_preds_c(), and write_tm_preds_h().

◆ constraints_by_letter_table

class constraint_data* constraints_by_letter_table[1<< CHAR_BIT]
static
Overview of all constraints beginning with a given letter.   

Referenced by add_constraint(), write_insn_constraint_len(), write_lookup_constraint_1(), and write_lookup_constraint_array().

◆ enum_order

◆ first_constraint

class constraint_data* first_constraint
static
For looking up all the constraints in the order that they appeared
in the machine description.   

◆ gen_constrs

bool gen_constrs
static

Referenced by main(), and parse_option().

◆ gen_header

bool gen_header
static
Argument parsing.   

Referenced by main(), main(), and parse_option().

◆ general_mem

char general_mem[] = { TARGET_MEM_CONSTRAINT, 0 }
static
Generate from machine description:
   - prototype declarations for operand predicates (tm-preds.h)
   - function definitions of operand predicates, if defined new-style
     (insn-preds.cc)
   Copyright (C) 2001-2024 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/>.   

Referenced by add_constraint().

◆ generic_constraint_letters

const char generic_constraint_letters[] = "g"
static
Contraint letters that have a special meaning and that cannot be used
in define*_constraints.   

Referenced by add_constraint().

◆ have_address_constraints

bool have_address_constraints
static

Referenced by add_constraint().

◆ have_const_int_constraints

bool have_const_int_constraints
static

◆ have_extra_constraints

bool have_extra_constraints
static

Referenced by add_constraint().

◆ have_memory_constraints

bool have_memory_constraints
static

Referenced by add_constraint().

◆ have_register_constraints

bool have_register_constraints
static

◆ have_relaxed_memory_constraints

bool have_relaxed_memory_constraints
static

Referenced by add_constraint().

◆ have_special_memory_constraints

bool have_special_memory_constraints
static

Referenced by add_constraint().

◆ last_constraint_ptr

class constraint_data** last_constraint_ptr = &first_constraint
static

Referenced by add_constraint().

◆ maybe_allows_mem_end

unsigned int maybe_allows_mem_end
static

◆ maybe_allows_mem_start

unsigned int maybe_allows_mem_start
static

◆ maybe_allows_none_end

unsigned int maybe_allows_none_end
static

◆ maybe_allows_none_start

unsigned int maybe_allows_none_start
static

◆ maybe_allows_reg_end

unsigned int maybe_allows_reg_end
static

◆ maybe_allows_reg_start

unsigned int maybe_allows_reg_start
static

◆ memory_end

unsigned int memory_end
static

◆ memory_start

unsigned int memory_start
static

◆ num_constraints

◆ register_end

unsigned int register_end
static

◆ register_start

unsigned int register_start
static

◆ relaxed_memory_end

unsigned int relaxed_memory_end
static

◆ relaxed_memory_start

unsigned int relaxed_memory_start
static

◆ satisfied_start

unsigned int satisfied_start
static

◆ special_memory_end

unsigned int special_memory_end
static

◆ special_memory_start

unsigned int special_memory_start
static