diff options
author | Palmer Dabbelt <palmer@dabbelt.com> | 2017-02-06 21:38:37 +0000 |
---|---|---|
committer | Palmer Dabbelt <palmer@gcc.gnu.org> | 2017-02-06 21:38:37 +0000 |
commit | 09cae7507d9e88f2b05cf3a9404bf181e65ccbac (patch) | |
tree | 4068c1ab645786d53f4bb817e680cf0963f2f03d /gcc/config/riscv/predicates.md | |
parent | 44a6da7bac79f288af814cd401a666c81fb8735c (diff) | |
download | gcc-09cae7507d9e88f2b05cf3a9404bf181e65ccbac.zip gcc-09cae7507d9e88f2b05cf3a9404bf181e65ccbac.tar.gz gcc-09cae7507d9e88f2b05cf3a9404bf181e65ccbac.tar.bz2 |
RISC-V Port: gcc
gcc/ChangeLog:
2017-02-06 Palmer Dabbelt <palmer@dabbelt.com>
* config/riscv/riscv.c: New file.
* gcc/common/config/riscv/riscv-common.c: Likewise.
* config.gcc: Likewise.
* config/riscv/constraints.md: Likewise.
* config/riscv/elf.h: Likewise.
* config/riscv/generic.md: Likewise.
* config/riscv/linux.h: Likewise.
* config/riscv/multilib-generator: Likewise.
* config/riscv/peephole.md: Likewise.
* config/riscv/pic.md: Likewise.
* config/riscv/predicates.md: Likewise.
* config/riscv/riscv-builtins.c: Likewise.
* config/riscv/riscv-c.c: Likewise.
* config/riscv/riscv-ftypes.def: Likewise.
* config/riscv/riscv-modes.def: Likewise.
* config/riscv/riscv-opts.h: Likewise.
* config/riscv/riscv-protos.h: Likewise.
* config/riscv/riscv.h: Likewise.
* config/riscv/riscv.md: Likewise.
* config/riscv/riscv.opt: Likewise.
* config/riscv/sync.md: Likewise.
* config/riscv/t-elf-multilib: Likewise.
* config/riscv/t-linux: Likewise.
* config/riscv/t-linux-multilib: Likewise.
* config/riscv/t-riscv: Likewise.
* configure.ac: Likewise.
* doc/contrib.texi: Add Kito Cheng, Palmer Dabbelt, and Andrew
Waterman as RISC-V maintainers.
* doc/install.texi: Add RISC-V entries.
* doc/invoke.texi: Add RISC-V options section.
* doc/md.texi: Add RISC-V constraints section.
From-SVN: r245224
Diffstat (limited to 'gcc/config/riscv/predicates.md')
-rw-r--r-- | gcc/config/riscv/predicates.md | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md new file mode 100644 index 0000000..854af14 --- /dev/null +++ b/gcc/config/riscv/predicates.md @@ -0,0 +1,180 @@ +;; Predicate description for RISC-V target. +;; Copyright (C) 2011-2017 Free Software Foundation, Inc. +;; Contributed by Andrew Waterman (andrew@sifive.com). +;; Based on MIPS target for GNU compiler. +;; +;; 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/>. + +(define_predicate "const_arith_operand" + (and (match_code "const_int") + (match_test "SMALL_OPERAND (INTVAL (op))"))) + +(define_predicate "arith_operand" + (ior (match_operand 0 "const_arith_operand") + (match_operand 0 "register_operand"))) + +(define_predicate "const_csr_operand" + (and (match_code "const_int") + (match_test "IN_RANGE (INTVAL (op), 0, 31)"))) + +(define_predicate "csr_operand" + (ior (match_operand 0 "const_csr_operand") + (match_operand 0 "register_operand"))) + +(define_predicate "sle_operand" + (and (match_code "const_int") + (match_test "SMALL_OPERAND (INTVAL (op) + 1)"))) + +(define_predicate "sleu_operand" + (and (match_operand 0 "sle_operand") + (match_test "INTVAL (op) + 1 != 0"))) + +(define_predicate "const_0_operand" + (and (match_code "const_int,const_wide_int,const_double,const_vector") + (match_test "op == CONST0_RTX (GET_MODE (op))"))) + +(define_predicate "reg_or_0_operand" + (ior (match_operand 0 "const_0_operand") + (match_operand 0 "register_operand"))) + +;; Only use branch-on-bit sequences when the mask is not an ANDI immediate. +(define_predicate "branch_on_bit_operand" + (and (match_code "const_int") + (match_test "INTVAL (op) >= IMM_BITS - 1"))) + +;; A legitimate CONST_INT operand that takes more than one instruction +;; to load. +(define_predicate "splittable_const_int_operand" + (match_code "const_int") +{ + /* Don't handle multi-word moves this way; we don't want to introduce + the individual word-mode moves until after reload. */ + if (GET_MODE_SIZE (mode) > UNITS_PER_WORD) + return false; + + /* Otherwise check whether the constant can be loaded in a single + instruction. */ + return !LUI_OPERAND (INTVAL (op)) && !SMALL_OPERAND (INTVAL (op)); +}) + +(define_predicate "move_operand" + (match_operand 0 "general_operand") +{ + enum riscv_symbol_type symbol_type; + + /* The thinking here is as follows: + + (1) The move expanders should split complex load sequences into + individual instructions. Those individual instructions can + then be optimized by all rtl passes. + + (2) The target of pre-reload load sequences should not be used + to store temporary results. If the target register is only + assigned one value, reload can rematerialize that value + on demand, rather than spill it to the stack. + + (3) If we allowed pre-reload passes like combine and cse to recreate + complex load sequences, we would want to be able to split the + sequences before reload as well, so that the pre-reload scheduler + can see the individual instructions. This falls foul of (2); + the splitter would be forced to reuse the target register for + intermediate results. + + (4) We want to define complex load splitters for combine. These + splitters can request a temporary scratch register, which avoids + the problem in (2). They allow things like: + + (set (reg T1) (high SYM)) + (set (reg T2) (low (reg T1) SYM)) + (set (reg X) (plus (reg T2) (const_int OFFSET))) + + to be combined into: + + (set (reg T3) (high SYM+OFFSET)) + (set (reg X) (lo_sum (reg T3) SYM+OFFSET)) + + if T2 is only used this once. */ + switch (GET_CODE (op)) + { + case CONST_INT: + return !splittable_const_int_operand (op, mode); + + case CONST: + case SYMBOL_REF: + case LABEL_REF: + return riscv_symbolic_constant_p (op, &symbol_type) + && !riscv_split_symbol_type (symbol_type); + + case HIGH: + op = XEXP (op, 0); + return riscv_symbolic_constant_p (op, &symbol_type) + && riscv_split_symbol_type (symbol_type) + && symbol_type != SYMBOL_PCREL; + + default: + return true; + } +}) + +(define_predicate "symbolic_operand" + (match_code "const,symbol_ref,label_ref") +{ + enum riscv_symbol_type type; + return riscv_symbolic_constant_p (op, &type); +}) + +(define_predicate "absolute_symbolic_operand" + (match_code "const,symbol_ref,label_ref") +{ + enum riscv_symbol_type type; + return (riscv_symbolic_constant_p (op, &type) + && (type == SYMBOL_ABSOLUTE || type == SYMBOL_PCREL)); +}) + +(define_predicate "plt_symbolic_operand" + (match_code "const,symbol_ref,label_ref") +{ + enum riscv_symbol_type type; + return (riscv_symbolic_constant_p (op, &type) + && type == SYMBOL_GOT_DISP && !SYMBOL_REF_WEAK (op) && TARGET_PLT); +}) + +(define_predicate "call_insn_operand" + (ior (match_operand 0 "absolute_symbolic_operand") + (match_operand 0 "plt_symbolic_operand") + (match_operand 0 "register_operand"))) + +(define_predicate "modular_operator" + (match_code "plus,minus,mult,ashift")) + +(define_predicate "equality_operator" + (match_code "eq,ne")) + +(define_predicate "order_operator" + (match_code "eq,ne,lt,ltu,le,leu,ge,geu,gt,gtu")) + +(define_predicate "signed_order_operator" + (match_code "eq,ne,lt,le,ge,gt")) + +(define_predicate "fp_native_comparison" + (match_code "eq,lt,le,gt,ge")) + +(define_predicate "fp_scc_comparison" + (match_code "unordered,ordered,unlt,unge,unle,ungt,ltgt,ne,eq,lt,le,gt,ge")) + +(define_predicate "fp_branch_comparison" + (match_code "unordered,ordered,unlt,unge,unle,ungt,uneq,ltgt,ne,eq,lt,le,gt,ge")) |