blob: 67ed3d286bbd528be1f5717e6353133eaf92a64d [file]
/* LoongArch static properties.
Copyright (C) 2021-2026 Free Software Foundation, Inc.
Contributed by Loongson Ltd.
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/>. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "loongarch-def.h"
#include "loongarch-str.h"
template <class T, int N>
using array = loongarch_def_array<T, N>;
template <class T>
using array_arch = array<T, N_ARCH_TYPES>;
template <class T>
using array_tune = array<T, N_TUNE_TYPES>;
array_arch<const char *> loongarch_arch_strings = array_arch<const char *> ()
.set (ARCH_NATIVE, STR_CPU_NATIVE)
.set (ARCH_ABI_DEFAULT, STR_ARCH_ABI_DEFAULT)
.set (ARCH_LOONGARCH64, STR_CPU_LOONGARCH64)
.set (ARCH_LA464, STR_CPU_LA464)
.set (ARCH_LA664, STR_CPU_LA664)
.set (ARCH_LA64V1_0, STR_ARCH_LA64V1_0)
.set (ARCH_LA64V1_1, STR_ARCH_LA64V1_1)
.set (ARCH_LA32V1_0, STR_ARCH_LA32V1_0)
.set (ARCH_LA32RV1_0, STR_ARCH_LA32RV1_0);
array_tune<const char *> loongarch_tune_strings = array_tune<const char *> ()
.set (TUNE_NATIVE, STR_CPU_NATIVE)
.set (TUNE_GENERIC, STR_TUNE_GENERIC)
.set (TUNE_LOONGARCH64, STR_CPU_LOONGARCH64)
.set (TUNE_LA464, STR_CPU_LA464)
.set (TUNE_LA664, STR_CPU_LA664)
.set (TUNE_LOONGARCH32, STR_TUNE_LOONGARCH32);
array_arch<loongarch_isa> loongarch_cpu_default_isa =
array_arch<loongarch_isa> ()
.set (ARCH_LOONGARCH64,
loongarch_isa ()
.base_ (ISA_BASE_LA64)
.fpu_ (ISA_EXT_FPU64))
.set (ARCH_LA464,
loongarch_isa ()
.base_ (ISA_BASE_LA64)
.fpu_ (ISA_EXT_FPU64)
.simd_ (ISA_EXT_SIMD_LASX))
.set (ARCH_LA664,
loongarch_isa ()
.base_ (ISA_BASE_LA64)
.fpu_ (ISA_EXT_FPU64)
.simd_ (ISA_EXT_SIMD_LASX)
.evolution_ (OPTION_MASK_ISA_DIV32 | OPTION_MASK_ISA_LD_SEQ_SA
| OPTION_MASK_ISA_LAM_BH | OPTION_MASK_ISA_LAMCAS
| OPTION_MASK_ISA_FRECIPE | OPTION_MASK_ISA_SCQ))
.set (ARCH_LA64V1_0,
loongarch_isa ()
.base_ (ISA_BASE_LA64)
.fpu_ (ISA_EXT_FPU64)
.simd_ (ISA_EXT_SIMD_LSX))
.set (ARCH_LA64V1_1,
loongarch_isa ()
.base_ (ISA_BASE_LA64)
.fpu_ (ISA_EXT_FPU64)
.simd_ (ISA_EXT_SIMD_LSX)
.evolution_ (OPTION_MASK_ISA_DIV32 | OPTION_MASK_ISA_LD_SEQ_SA
| OPTION_MASK_ISA_LAM_BH | OPTION_MASK_ISA_LAMCAS
| OPTION_MASK_ISA_FRECIPE | OPTION_MASK_ISA_SCQ))
.set (ARCH_LA32V1_0,
loongarch_isa ()
.base_ (ISA_BASE_LA32)
.fpu_ (ISA_EXT_NONE))
.set (ARCH_LA32RV1_0,
loongarch_isa ()
.base_ (ISA_BASE_LA32R)
.fpu_ (ISA_EXT_NONE));
static inline loongarch_cache la464_cache ()
{
return loongarch_cache ()
.l1d_line_size_ (64)
.l1d_size_ (64)
.l2d_size_ (256)
.simultaneous_prefetches_ (4);
}
array_tune<loongarch_cache> loongarch_cpu_cache =
array_tune<loongarch_cache> ()
.set (TUNE_GENERIC, la464_cache ())
.set (TUNE_LOONGARCH64, la464_cache ())
.set (TUNE_LA464, la464_cache ())
.set (TUNE_LA664, la464_cache ())
.set (TUNE_LOONGARCH32, la464_cache ());
static inline loongarch_align la464_align ()
{
return loongarch_align ().function_ ("32").loop_ ("8").jump_ ("32").label_ ("8");
}
static inline loongarch_align la664_align ()
{
return loongarch_align ().function_ ("16").loop_ ("16").jump_ ("32").label_ ("8");
}
array_tune<loongarch_align> loongarch_cpu_align =
array_tune<loongarch_align> ()
.set (TUNE_GENERIC, la664_align ())
.set (TUNE_LOONGARCH64, la664_align ())
.set (TUNE_LA464, la464_align ())
.set (TUNE_LA664, la664_align ())
.set (TUNE_LOONGARCH32, la664_align ());
/* Default RTX cost initializer. */
loongarch_rtx_cost_data::loongarch_rtx_cost_data ()
: fp_add (COSTS_N_INSNS (5)),
fp_mult_sf (COSTS_N_INSNS (5)),
fp_mult_df (COSTS_N_INSNS (5)),
fp_div_sf (COSTS_N_INSNS (8)),
fp_div_df (COSTS_N_INSNS (8)),
int_mult_si (COSTS_N_INSNS (4)),
int_mult_di (COSTS_N_INSNS (4)),
int_div_si (COSTS_N_INSNS (5)),
int_div_di (COSTS_N_INSNS (5)),
movcf2gr (COSTS_N_INSNS (7)),
movgr2cf (COSTS_N_INSNS (15)),
branch_cost (6),
addr_reg_reg_cost (3),
memory_latency (4) {}
/* The following properties cannot be looked up directly using "cpucfg".
So it is necessary to provide a default value for "unknown native"
tune targets (i.e. -mtune=native while PRID does not correspond to
any known "-mtune" type). */
array_tune<loongarch_rtx_cost_data> loongarch_cpu_rtx_cost_data =
array_tune<loongarch_rtx_cost_data> ()
.set (TUNE_LA664,
loongarch_rtx_cost_data ()
.movcf2gr_ (COSTS_N_INSNS (1))
.movgr2cf_ (COSTS_N_INSNS (1)));
/* RTX costs to use when optimizing for size.
We use a value slightly larger than COSTS_N_INSNS (1) for all of them
because they are slower than simple instructions. */
#define COST_COMPLEX_INSN (COSTS_N_INSNS (1) + 1)
const loongarch_rtx_cost_data loongarch_rtx_cost_optimize_size =
loongarch_rtx_cost_data ()
.fp_add_ (COST_COMPLEX_INSN)
.fp_mult_sf_ (COST_COMPLEX_INSN)
.fp_mult_df_ (COST_COMPLEX_INSN)
.fp_div_sf_ (COST_COMPLEX_INSN)
.fp_div_df_ (COST_COMPLEX_INSN)
.int_mult_si_ (COST_COMPLEX_INSN)
.int_mult_di_ (COST_COMPLEX_INSN)
.int_div_si_ (COST_COMPLEX_INSN)
.int_div_di_ (COST_COMPLEX_INSN)
.movcf2gr_ (COST_COMPLEX_INSN);
array_tune<int> loongarch_cpu_issue_rate = array_tune<int> ()
.set (TUNE_NATIVE, 4)
.set (TUNE_GENERIC, 4)
.set (TUNE_LOONGARCH64, 4)
.set (TUNE_LA464, 4)
.set (TUNE_LA664, 6)
.set (TUNE_LOONGARCH32, 4);
array_tune<int> loongarch_cpu_multipass_dfa_lookahead = array_tune<int> ()
.set (TUNE_NATIVE, 4)
.set (TUNE_GENERIC, 4)
.set (TUNE_LOONGARCH64, 4)
.set (TUNE_LA464, 4)
.set (TUNE_LA664, 6)
.set (TUNE_LOONGARCH32, 4);
/* Wiring string definitions from loongarch-str.h to global arrays
with standard index values from loongarch-opts.h, so we can
print config-related messages and do ABI self-spec filtering
from the driver in a self-consistent manner. */
array<const char *, N_ISA_BASE_TYPES> loongarch_isa_base_strings =
array<const char *, N_ISA_BASE_TYPES> ()
.set (ISA_BASE_LA32, STR_ISA_BASE_LA32)
.set (ISA_BASE_LA32R, STR_ISA_BASE_LA32R)
.set (ISA_BASE_LA64, STR_ISA_BASE_LA64);
array<const char *, N_ISA_EXT_TYPES> loongarch_isa_ext_strings =
array<const char *, N_ISA_EXT_TYPES> ()
.set (ISA_EXT_NONE, STR_NONE)
.set (ISA_EXT_FPU32, STR_ISA_EXT_FPU32)
.set (ISA_EXT_FPU64, STR_ISA_EXT_FPU64)
.set (ISA_EXT_SIMD_LSX, STR_ISA_EXT_LSX)
.set (ISA_EXT_SIMD_LASX, STR_ISA_EXT_LASX);
array<const char *, N_ABI_BASE_TYPES> loongarch_abi_base_strings =
array<const char *, N_ABI_BASE_TYPES> ()
.set (ABI_BASE_ILP32D, STR_ABI_BASE_ILP32D)
.set (ABI_BASE_ILP32F, STR_ABI_BASE_ILP32F)
.set (ABI_BASE_ILP32S, STR_ABI_BASE_ILP32S)
.set (ABI_BASE_LP64D, STR_ABI_BASE_LP64D)
.set (ABI_BASE_LP64F, STR_ABI_BASE_LP64F)
.set (ABI_BASE_LP64S, STR_ABI_BASE_LP64S);
array<const char *, N_ABI_EXT_TYPES> loongarch_abi_ext_strings =
array<const char *, N_ABI_EXT_TYPES> ()
.set (ABI_EXT_BASE, STR_ABI_EXT_BASE);
array<const char *, N_CMODEL_TYPES> loongarch_cmodel_strings =
array<const char *, N_CMODEL_TYPES> ()
.set (CMODEL_NORMAL, STR_CMODEL_NORMAL)
.set (CMODEL_TINY, STR_CMODEL_TINY)
.set (CMODEL_TINY_STATIC, STR_CMODEL_TS)
.set (CMODEL_MEDIUM, STR_CMODEL_MEDIUM)
.set (CMODEL_LARGE, STR_CMODEL_LARGE)
.set (CMODEL_EXTREME, STR_CMODEL_EXTREME);
array<array<loongarch_isa, N_ABI_EXT_TYPES>, N_ABI_BASE_TYPES>
abi_minimal_isa = array<array<loongarch_isa, N_ABI_EXT_TYPES>,
N_ABI_BASE_TYPES> ()
.set (ABI_BASE_ILP32D,
array<loongarch_isa, N_ABI_EXT_TYPES> ()
.set (ABI_EXT_BASE,
loongarch_isa ()
.base_ (ISA_BASE_LA32R)
.fpu_ (ISA_EXT_FPU64)))
.set (ABI_BASE_ILP32F,
array<loongarch_isa, N_ABI_EXT_TYPES> ()
.set (ABI_EXT_BASE,
loongarch_isa ()
.base_ (ISA_BASE_LA32R)
.fpu_ (ISA_EXT_FPU32)))
.set (ABI_BASE_ILP32S,
array<loongarch_isa, N_ABI_EXT_TYPES> ()
.set (ABI_EXT_BASE,
loongarch_isa ().base_ (ISA_BASE_LA32R)))
.set (ABI_BASE_LP64D,
array<loongarch_isa, N_ABI_EXT_TYPES> ()
.set (ABI_EXT_BASE,
loongarch_isa ()
.base_ (ISA_BASE_LA64)
.fpu_ (ISA_EXT_FPU64)))
.set (ABI_BASE_LP64F,
array<loongarch_isa, N_ABI_EXT_TYPES> ()
.set (ABI_EXT_BASE,
loongarch_isa ()
.base_ (ISA_BASE_LA64)
.fpu_ (ISA_EXT_FPU32)))
.set (ABI_BASE_LP64S,
array<loongarch_isa, N_ABI_EXT_TYPES> ()
.set (ABI_EXT_BASE,
loongarch_isa ().base_ (ISA_BASE_LA64)));