/* SPDX-License-Identifier: GPL-3.0-or-later * * Microcode programmable logic matrix analyzer. * Copyright 2015-2020 Viacheslav Ovsiienko <1801BM1@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * This program 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 this program. If not, see . */ #pragma once #define _CRT_SECURE_NO_DEPRECATE 1 #if defined(_WIN32) || defined(_WIN64) #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #define PLM_S_MAX 48 /* maximal width of Sum-of-Products */ #define PLM_P_MAX 400 /* maximal number of products supported */ #define PLM_NA_MAX_BITS 9 /* the maximal Next Address field */ #define PLM_M_TREE_BITS 4 /* the number of bits M optimization */ #define PLM_M_TREE (1u << PLM_M_TREE_BITS) #define PLM_NA_MAX (1u << PLM_NA_MAX_BITS) #define MCODE_PARAM_LEN 80 #define FILE_BUF_WORDS 0x10000 #define FILE_MAX_ERRORS 0x100 enum plm_type { PLM_TYPE_NONE = 0, PLM_TYPE_VM1A_MAIN, PLM_TYPE_VM1G_MAIN, PLM_TYPE_VM2_MAIN, PLM_TYPE_F11_CS0, PLM_TYPE_F11_CS1, PLM_TYPE_F11_CS2, PLM_TYPE_F11_NA_CLR0, PLM_TYPE_VM2_DEC, PLM_TYPE_VM3_DEC, PLM_TYPE_VM3_MAIN, }; enum opt_type { PLM_OPT_NONE, PLM_OPT_32, /* Direct matrix calculation over */ PLM_OPT_64, /* all configured products */ PLM_OPT_128, PLM_OPT_256, PLM_OPT_32_TREE, /* Matrix calculation over M-tree */ PLM_OPT_64_TREE, /* M-tree is ver simplified */ PLM_OPT_128_TREE, /* It has the single root */ PLM_OPT_256_TREE, /* with M leaves */ }; /* Programmable logic matrix descriptor to init */ struct plm_desc { const char *p[PLM_P_MAX]; const int16_t *s[PLM_S_MAX]; uint64_t xout; /* Final inversion mask */ uint32_t xin; /* Input inversion mask */ uint8_t in_nb; /* Input bitwidth */ uint8_t out_nb; /* Output bitwidth */ uint8_t na_nb; /* Number of next address bits */ uint8_t na_bits[PLM_NA_MAX_BITS]; }; struct plm_p { uint32_t xor; uint32_t and; uint64_t sop; }; struct plm_p32 { uint32_t xor; uint32_t and; uint64_t sop; }; struct plm_p64 { uint64_t xor; uint64_t and; uint64_t sop[2]; }; struct plm_p128 { union { uint32_t xor32[4]; __m128i xor; }; union { uint32_t and32[4]; __m128i and; }; union { uint64_t sop64[4]; __m128i sop[2]; }; }; struct plm_p256 { union { uint32_t xor32[8]; __m256i xor; }; union { uint32_t and32[8]; __m256i and; }; union { uint64_t sop64[8]; __m256i sop[2]; }; }; /* Packed array for vector optimizations */ struct plm_n { uint32_t n; union { struct plm_p32 p32[PLM_P_MAX]; struct plm_p64 p64[PLM_P_MAX / 2]; struct plm_p128 p128[PLM_P_MAX / 4]; struct plm_p256 p256[PLM_P_MAX / 8]; }; }; /* Programmable logic matrix object */ struct plm { uint16_t type; /* Matrix type initialized */ uint16_t opt; /* Optimization type configured */ uint16_t p_min; /* Minimal index of product */ uint16_t p_max; /* Maximal index of product */ uint64_t (*get)(const struct plm *mx, uint32_t val); uint64_t p_xout; /* Final inversion mask */ uint32_t p_xin; /* Input inversion mask */ uint8_t in_nb; /* Input bitwidth */ uint8_t out_nb; /* Output bitwidth */ uint8_t na_nb; uint8_t na_bits[PLM_NA_MAX_BITS]; uint8_t mt_bits[PLM_M_TREE_BITS]; struct plm_p p[PLM_P_MAX]; struct plm_n tree[PLM_M_TREE]; }; struct plm_scan { uint8_t b[PLM_M_TREE_BITS]; uint8_t o[PLM_M_TREE_BITS]; uint32_t hmin; }; extern const struct plm_desc plm_desc_vm1a; extern const struct plm_desc plm_desc_vm1g; extern const struct plm_desc plm_desc_vm2; extern const struct plm_desc plm_desc_vm3; extern const struct plm_desc plm_desc_vm2_dec; extern const struct plm_desc plm_desc_vm3_dec; extern const struct plm_desc plm_desc_f11_cs0; extern const struct plm_desc plm_desc_f11_cs1; extern const struct plm_desc plm_desc_f11_cs2; extern const struct plm_desc plm_desc_f11_na_clr0; extern int32_t cl_ab; extern int32_t cl_ae; extern int32_t cl_as; extern int32_t cl_az; extern int32_t cl_op; extern int32_t cl_om; extern int64_t cl_qv; extern int64_t cl_qm; extern int32_t cl_qmc; /* Programmable logic matrix API */ int plm_init(struct plm *plm, enum plm_type type); int plm_opt(struct plm *plm, enum opt_type opt); void plm_show_tree(const struct plm *plm); static inline uint64_t plm_get(const struct plm *plm, uint32_t value) { return plm->get(plm, value); } struct ma_stats { struct { uint32_t count; uint32_t zeros; uint32_t ones; } jmp[PLM_NA_MAX]; uint32_t uops; }; void mc_test_ref(enum plm_type type, enum opt_type opt, const char *text); void mc_mterm_match(enum plm_type type, enum opt_type opt, const char *fname, const char *text); void mc_mterm_write(enum plm_type type, enum opt_type opt, const char *fname, const char *text); void mc_test_qmc16(const struct plm *tpl); #define SIMD_MMX (1u << 0) #define SIMD_SSE (1u << 1) #define SIMD_SSE2 (1u << 2) #define SIMD_SSE3 (1u << 3) #define SIMD_SSSE3 (1u << 4) #define SIMD_SSE41 (1u << 5) #define SIMD_SSE42 (1u << 6) #define SIMD_AVX (1u << 7) #define SIMD_AVX2 (1u << 8) uint32_t mc_query_simd(void); uint64_t mc_query_ms(void); #ifndef MIN #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif #ifndef MAX #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif