blob: 556b5c552537be88dd7ab1cb831bd2123ad60ede [file] [log] [blame]
/* Extra machine modes for RISC-V target.
Copyright (C) 2011-2022 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/>. */
FLOAT_MODE (HF, 2, ieee_half_format);
FLOAT_MODE (TF, 16, ieee_quad_format);
/* Vector modes. */
/* Encode the ratio of SEW/LMUL into the mask types. There are the following
* mask types. */
/* | Mode | MIN_VLEN = 32 | MIN_VLEN = 64 |
| | SEW/LMUL | SEW/LMUL |
| VNx1BI | 32 | 64 |
| VNx2BI | 16 | 32 |
| VNx4BI | 8 | 16 |
| VNx8BI | 4 | 8 |
| VNx16BI | 2 | 4 |
| VNx32BI | 1 | 2 |
| VNx64BI | N/A | 1 | */
/* For RVV modes, each boolean value occupies 1-bit.
4th argument is specify the minmial possible size of the vector mode,
and will adjust to the right size by ADJUST_BYTESIZE. */
VECTOR_BOOL_MODE (VNx1BI, 1, BI, 1);
VECTOR_BOOL_MODE (VNx2BI, 2, BI, 1);
VECTOR_BOOL_MODE (VNx4BI, 4, BI, 1);
VECTOR_BOOL_MODE (VNx8BI, 8, BI, 1);
VECTOR_BOOL_MODE (VNx16BI, 16, BI, 2);
VECTOR_BOOL_MODE (VNx32BI, 32, BI, 4);
VECTOR_BOOL_MODE (VNx64BI, 64, BI, 8);
ADJUST_NUNITS (VNx1BI, riscv_v_adjust_nunits (VNx1BImode, 1));
ADJUST_NUNITS (VNx2BI, riscv_v_adjust_nunits (VNx2BImode, 2));
ADJUST_NUNITS (VNx4BI, riscv_v_adjust_nunits (VNx4BImode, 4));
ADJUST_NUNITS (VNx8BI, riscv_v_adjust_nunits (VNx8BImode, 8));
ADJUST_NUNITS (VNx16BI, riscv_v_adjust_nunits (VNx16BImode, 16));
ADJUST_NUNITS (VNx32BI, riscv_v_adjust_nunits (VNx32BImode, 32));
ADJUST_NUNITS (VNx64BI, riscv_v_adjust_nunits (VNx64BImode, 64));
ADJUST_ALIGNMENT (VNx1BI, 1);
ADJUST_ALIGNMENT (VNx2BI, 1);
ADJUST_ALIGNMENT (VNx4BI, 1);
ADJUST_ALIGNMENT (VNx8BI, 1);
ADJUST_ALIGNMENT (VNx16BI, 1);
ADJUST_ALIGNMENT (VNx32BI, 1);
ADJUST_ALIGNMENT (VNx64BI, 1);
ADJUST_BYTESIZE (VNx1BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
ADJUST_BYTESIZE (VNx2BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
ADJUST_BYTESIZE (VNx4BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
ADJUST_BYTESIZE (VNx8BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
ADJUST_BYTESIZE (VNx16BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
ADJUST_BYTESIZE (VNx32BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
ADJUST_BYTESIZE (VNx64BI, riscv_v_adjust_nunits (VNx64BImode, 8));
/*
| Mode | MIN_VLEN=32 | MIN_VLEN=32 | MIN_VLEN=64 | MIN_VLEN=64 |
| | LMUL | SEW/LMUL | LMUL | SEW/LMUL |
| VNx1QI | MF4 | 32 | MF8 | 64 |
| VNx2QI | MF2 | 16 | MF4 | 32 |
| VNx4QI | M1 | 8 | MF2 | 16 |
| VNx8QI | M2 | 4 | M1 | 8 |
| VNx16QI | M4 | 2 | M2 | 4 |
| VNx32QI | M8 | 1 | M4 | 2 |
| VNx64QI | N/A | N/A | M8 | 1 |
| VNx1(HI|HF) | MF2 | 32 | MF4 | 64 |
| VNx2(HI|HF) | M1 | 16 | MF2 | 32 |
| VNx4(HI|HF) | M2 | 8 | M1 | 16 |
| VNx8(HI|HF) | M4 | 4 | M2 | 8 |
| VNx16(HI|HF)| M8 | 2 | M4 | 4 |
| VNx32(HI|HF)| N/A | N/A | M8 | 2 |
| VNx1(SI|SF) | M1 | 32 | MF2 | 64 |
| VNx2(SI|SF) | M2 | 16 | M1 | 32 |
| VNx4(SI|SF) | M4 | 8 | M2 | 16 |
| VNx8(SI|SF) | M8 | 4 | M4 | 8 |
| VNx16(SI|SF)| N/A | N/A | M8 | 4 |
| VNx1(DI|DF) | N/A | N/A | M1 | 64 |
| VNx2(DI|DF) | N/A | N/A | M2 | 32 |
| VNx4(DI|DF) | N/A | N/A | M4 | 16 |
| VNx8(DI|DF) | N/A | N/A | M8 | 8 |
*/
/* Define RVV modes whose sizes are multiples of 64-bit chunks. */
#define RVV_MODES(NVECS, VB, VH, VS, VD) \
VECTOR_MODES_WITH_PREFIX (VNx, INT, 8 * NVECS, 0); \
VECTOR_MODES_WITH_PREFIX (VNx, FLOAT, 8 * NVECS, 0); \
\
ADJUST_NUNITS (VB##QI, riscv_v_adjust_nunits (VB##QI##mode, NVECS * 8)); \
ADJUST_NUNITS (VH##HI, riscv_v_adjust_nunits (VH##HI##mode, NVECS * 4)); \
ADJUST_NUNITS (VS##SI, riscv_v_adjust_nunits (VS##SI##mode, NVECS * 2)); \
ADJUST_NUNITS (VD##DI, riscv_v_adjust_nunits (VD##DI##mode, NVECS)); \
ADJUST_NUNITS (VH##HF, riscv_v_adjust_nunits (VH##HF##mode, NVECS * 4)); \
ADJUST_NUNITS (VS##SF, riscv_v_adjust_nunits (VS##SF##mode, NVECS * 2)); \
ADJUST_NUNITS (VD##DF, riscv_v_adjust_nunits (VD##DF##mode, NVECS)); \
\
ADJUST_ALIGNMENT (VB##QI, 1); \
ADJUST_ALIGNMENT (VH##HI, 2); \
ADJUST_ALIGNMENT (VS##SI, 4); \
ADJUST_ALIGNMENT (VD##DI, 8); \
ADJUST_ALIGNMENT (VH##HF, 2); \
ADJUST_ALIGNMENT (VS##SF, 4); \
ADJUST_ALIGNMENT (VD##DF, 8);
/* 'VECTOR_MODES_WITH_PREFIX' does not allow ncomponents < 2.
So we use 'VECTOR_MODE_WITH_PREFIX' to define VNx1DImode and VNx1DFmode. */
VECTOR_MODE_WITH_PREFIX (VNx, INT, DI, 1, 0);
VECTOR_MODE_WITH_PREFIX (VNx, FLOAT, DF, 1, 0);
RVV_MODES (1, VNx8, VNx4, VNx2, VNx1)
RVV_MODES (2, VNx16, VNx8, VNx4, VNx2)
RVV_MODES (4, VNx32, VNx16, VNx8, VNx4)
RVV_MODES (8, VNx64, VNx32, VNx16, VNx8)
VECTOR_MODES_WITH_PREFIX (VNx, INT, 4, 0);
VECTOR_MODES_WITH_PREFIX (VNx, FLOAT, 4, 0);
ADJUST_NUNITS (VNx4QI, riscv_v_adjust_nunits (VNx4QImode, 4));
ADJUST_NUNITS (VNx2HI, riscv_v_adjust_nunits (VNx2HImode, 2));
ADJUST_NUNITS (VNx2HF, riscv_v_adjust_nunits (VNx2HFmode, 2));
ADJUST_ALIGNMENT (VNx4QI, 1);
ADJUST_ALIGNMENT (VNx2HI, 2);
ADJUST_ALIGNMENT (VNx2HF, 2);
/* 'VECTOR_MODES_WITH_PREFIX' does not allow ncomponents < 2.
So we use 'VECTOR_MODE_WITH_PREFIX' to define VNx1SImode and VNx1SFmode. */
VECTOR_MODE_WITH_PREFIX (VNx, INT, SI, 1, 0);
VECTOR_MODE_WITH_PREFIX (VNx, FLOAT, SF, 1, 0);
ADJUST_NUNITS (VNx1SI, riscv_v_adjust_nunits (VNx1SImode, 1));
ADJUST_NUNITS (VNx1SF, riscv_v_adjust_nunits (VNx1SFmode, 1));
ADJUST_ALIGNMENT (VNx1SI, 4);
ADJUST_ALIGNMENT (VNx1SF, 4);
VECTOR_MODES_WITH_PREFIX (VNx, INT, 2, 0);
ADJUST_NUNITS (VNx2QI, riscv_v_adjust_nunits (VNx2QImode, 2));
ADJUST_ALIGNMENT (VNx2QI, 1);
/* 'VECTOR_MODES_WITH_PREFIX' does not allow ncomponents < 2.
So we use 'VECTOR_MODE_WITH_PREFIX' to define VNx1HImode and VNx1HFmode. */
VECTOR_MODE_WITH_PREFIX (VNx, INT, HI, 1, 0);
VECTOR_MODE_WITH_PREFIX (VNx, FLOAT, HF, 1, 0);
ADJUST_NUNITS (VNx1HI, riscv_v_adjust_nunits (VNx1HImode, 1));
ADJUST_NUNITS (VNx1HF, riscv_v_adjust_nunits (VNx1HFmode, 1));
ADJUST_ALIGNMENT (VNx1HI, 2);
ADJUST_ALIGNMENT (VNx1HF, 2);
/* 'VECTOR_MODES_WITH_PREFIX' does not allow ncomponents < 2.
So we use 'VECTOR_MODE_WITH_PREFIX' to define VNx1QImode. */
VECTOR_MODE_WITH_PREFIX (VNx, INT, QI, 1, 0);
ADJUST_NUNITS (VNx1QI, riscv_v_adjust_nunits (VNx1QImode, 1));
ADJUST_ALIGNMENT (VNx1QI, 1);
/* TODO: According to RISC-V 'V' ISA spec, the maximun vector length can
be 65536 for a single vector register which means the vector mode in
GCC can be maximum = 65536 * 8 bits (LMUL=8).
However, 'GET_MODE_SIZE' is using poly_uint16/unsigned short which will
overflow if we specify vector-length = 65536. To support this feature,
we need to change the codes outside the RISC-V port. We will support it in
the future. */
#define MAX_BITSIZE_MODE_ANY_MODE (4096 * 8)
/* Coefficient 1 is multiplied by the number of 64-bit/32-bit chunks in a vector
minus one. */
#define NUM_POLY_INT_COEFFS 2