Mercurial > vec
view gen/genlib.h @ 45:7955bed1d169 default tip
*: add preliminary floating point support
no x86 intrinsics just yet, but I did add altivec since it's
(arguably) the simplest :)
author | Paper <paper@tflc.us> |
---|---|
date | Wed, 30 Apr 2025 18:36:38 -0400 |
parents | |
children |
line wrap: on
line source
/** * vec - a tiny SIMD vector library in C99 * * Copyright (c) 2024-2025 Paper * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. **/ #include <stdio.h> #include <stdlib.h> #include <string.h> enum { OP_SPLAT, OP_LOAD_ALIGNED, OP_LOAD, OP_STORE_ALIGNED, OP_STORE, OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_MOD, OP_AVG, OP_AND, OP_OR, OP_XOR, OP_NOT, OP_CMPLT, OP_CMPEQ, OP_CMPGT, OP_CMPLE, /* these are after the other ones to make */ OP_CMPGE, /* implementing them as simple as NOT(CMPLT|CMPGT) */ OP_MIN, OP_MAX, OP_RSHIFT, OP_LRSHIFT, OP_LSHIFT, /* use this for array sizes and the like */ OP_FINAL_, }; enum { TYPE_INT, /* signed int */ TYPE_UINT, /* unsigned int */ TYPE_FLOAT, /* IEEE float */ }; struct op_info { const char *u; const char *l; /* print return type to stdout */ void (*pret)(int op, int type, int bits, int size); /* print params type to stdout */ void (*pparam)(int op, int type, int bits, int size); }; struct strs { const char *l; const char *u; }; extern struct strs type_str[]; struct op_info *gen_op_info(int op); struct op_impl { /* return 1 if it's implemented for a specific set of * inputs :) * * if this function is not implemented, and `pbody` * is not NULL, then it is assumed that there are * no restrictions on what type, bits, or size can * be used. beware! */ int (*check)(int op, int type, int bits, int size); /* prints any additional preprocessor checks needed * should start with a conditional, usually && */ void (*ppcheck)(int op, int type, int bits, int size); /* sherman? * (this prints the actual body of the function...) */ void (*pbody)(int op, int type, int bits, int size); }; int gen(struct op_impl op_impl[OP_FINAL_], const char *name); void gen_print_vtype(int type, int bits, int size); void gen_print_stype(int type, int bits);