/* * (c) 2022 Petr Ročkai * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #pragma once #include "types.hpp" namespace bast { inline namespace opcodes { template< word val, int count > constexpr void maxbits() { static_assert( val < ( 1 << count ) ); } constexpr void maxbits( word val, int count ) { if ( val >= ( 1 << count ) ) __builtin_trap(); } constexpr word block_label( label id = { 0 } ) { maxbits( id.v, 20 ); return 0xaa000000 | id.v; } constexpr word block_next ( label id = { 0 } ) { maxbits( id.v, 20 ); return 0xaa100000 | id.v; } constexpr word block_push ( label id = { 0 } ) { maxbits( id.v, 20 ); return 0xaa200000 | id.v; } constexpr word push_half ( half h = 0 ) { return 0xaa300000 | h; } constexpr word push_upper( half h = 0 ) { return 0xaa310000 | h; } constexpr word push_type ( half t = 0 ) { maxbits( t, 12 ); return 0xaa320000 | t; } constexpr word push_type ( half t1, half t2 ) { maxbits( t1, 8 ); maxbits( t2, 8 ); return 0xaa320000 | t1 << 8 | t2; } constexpr word swap_at( half d1 = 0, half d2 = 0 ) { maxbits( d1, 4 ); return 0xaa400000 | d1 << 16 | d2; } constexpr word fail = 0xaa500000; constexpr word cancel = 0xaa500001; using bast::type_id; constexpr word make_opcode( word type_id, word op ) { maxbits( type_id, 12 ); maxbits( op, 12 ); if ( type_id == 0 ) return op; else return 0xab000000 | type_id << 12 | op; } template< typename T, word op = 0 > constexpr word opcode = make_opcode( type_id< T >, op ); template< typename T = void > constexpr word gen_drop = opcode< T, 0xfff >; template< typename T = void > constexpr word gen_dup = opcode< T, 0xffe >; template< typename T = void > constexpr word gen_zero = opcode< T, 0x000 >; template< typename T = void > constexpr word bv_zero = opcode< T, 0x000 >; template< typename T = void > constexpr word bv_const = opcode< T, 0x001 >; template< typename T = void > constexpr word bv_add = opcode< T, 0x010 >; template< typename T = void > constexpr word bv_sub = opcode< T, 0x011 >; template< typename T = void > constexpr word bv_mul = opcode< T, 0x012 >; template< typename T = void > constexpr word bv_sdiv = opcode< T, 0x013 >; template< typename T = void > constexpr word bv_udiv = opcode< T, 0x014 >; template< typename T = void > constexpr word bv_srem = opcode< T, 0x015 >; template< typename T = void > constexpr word bv_urem = opcode< T, 0x016 >; template< typename T = void > constexpr word bv_and = opcode< T, 0x020 >; template< typename T = void > constexpr word bv_or = opcode< T, 0x021 >; template< typename T = void > constexpr word bv_xor = opcode< T, 0x022 >; template< typename T = void > constexpr word bv_neg = opcode< T, 0x023 >; template< typename T = void > constexpr word bv_shl = opcode< T, 0x024 >; template< typename T = void > constexpr word bv_lshr = opcode< T, 0x025 >; template< typename T = void > constexpr word bv_ashr = opcode< T, 0x026 >; template< typename T = void > constexpr word bv_eq = opcode< T, 0x030 >; template< typename T = void > constexpr word bv_neq = opcode< T, 0x031 >; template< typename T = void > constexpr word bv_ule = opcode< T, 0x032 >; template< typename T = void > constexpr word bv_ult = opcode< T, 0x033 >; template< typename T = void > constexpr word bv_ugt = opcode< T, 0x034 >; template< typename T = void > constexpr word bv_uge = opcode< T, 0x035 >; template< typename T = void > constexpr word bv_sle = opcode< T, 0x036 >; template< typename T = void > constexpr word bv_slt = opcode< T, 0x037 >; template< typename T = void > constexpr word bv_sgt = opcode< T, 0x038 >; template< typename T = void > constexpr word bv_sge = opcode< T, 0x039 >; template< typename T = void > constexpr word bv_zext_b = opcode< T, 0x050 >; // byte → * template< typename T = void > constexpr word bv_zext_h = opcode< T, 0x051 >; // half → * template< typename T = void > constexpr word bv_zext_w = opcode< T, 0x052 >; // word → * template< typename T = void > constexpr word bv_sext_b = opcode< T, 0x053 >; // byte → * template< typename T = void > constexpr word bv_sext_h = opcode< T, 0x054 >; // half → * template< typename T = void > constexpr word bv_sext_w = opcode< T, 0x055 >; // word → * template< typename T = void > constexpr word bv_trunc_h = opcode< T, 0x056 >; // half → * template< typename T = void > constexpr word bv_trunc_w = opcode< T, 0x057 >; // word → * template< typename T = void > constexpr word bv_trunc_d = opcode< T, 0x058 >; // dyad → * template< typename T = void > constexpr word bv_guard_zero = opcode< T, 0x060 >; template< typename T = void > constexpr word bv_guard_nonzero = opcode< T, 0x061 >; template< typename T = void > constexpr word bv_assert_zero = opcode< T, 0x070 >; template< typename T = void > constexpr word bv_assert_nonzero = opcode< T, 0x071 >; constexpr word type_type = opcode< type, 0x000 >; constexpr word type_byte = opcode< type, 0x001 >; constexpr word type_half = opcode< type, 0x002 >; constexpr word type_word = opcode< type, 0x003 >; constexpr word type_dyad = opcode< type, 0x004 >; constexpr word type_dict = opcode< type, 0x005 >; constexpr word dict_zero = gen_zero< dict >; constexpr word dict_dup = gen_dup< dict >; constexpr word dict_set = opcode< dict, 0x001 >; constexpr word dict_get = opcode< dict, 0x002 >; constexpr word dict_take = opcode< dict, 0x003 >; constexpr word byte_const = bv_const< byte >; constexpr word byte_zero = bv_zero < byte >; constexpr word byte_dup = gen_dup < byte >; constexpr word byte_drop = gen_drop< byte >; constexpr word byte_trunc_h = bv_trunc_h< byte >; constexpr word byte_trunc_w = bv_trunc_w< byte >; constexpr word byte_trunc_d = bv_trunc_d< byte >; constexpr word byte_add = bv_add < byte >; constexpr word byte_sub = bv_sub < byte >; constexpr word byte_mul = bv_mul < byte >; constexpr word byte_sdiv = bv_sdiv< byte >; constexpr word byte_udiv = bv_udiv< byte >; constexpr word byte_srem = bv_srem< byte >; constexpr word byte_urem = bv_urem< byte >; constexpr word byte_and = bv_and < byte >; constexpr word byte_or = bv_or < byte >; constexpr word byte_xor = bv_xor < byte >; constexpr word byte_neg = bv_neg < byte >; constexpr word byte_shl = bv_shl < byte >; constexpr word byte_lshr = bv_lshr< byte >; constexpr word byte_ashr = bv_ashr< byte >; constexpr word byte_eq = bv_eq < byte >; constexpr word byte_neq = bv_neq< byte >; constexpr word byte_ule = bv_ule< byte >; constexpr word byte_ult = bv_ult< byte >; constexpr word byte_ugt = bv_ugt< byte >; constexpr word byte_uge = bv_uge< byte >; constexpr word byte_sle = bv_sle< byte >; constexpr word byte_slt = bv_slt< byte >; constexpr word byte_sgt = bv_sgt< byte >; constexpr word byte_sge = bv_sge< byte >; constexpr word byte_guard_zero = bv_guard_zero< byte >; constexpr word byte_guard_nonzero = bv_guard_nonzero< byte >; /* half (16 bit) operations */ constexpr word half_const = bv_const< half >; constexpr word half_zero = bv_zero < half >; constexpr word half_dup = gen_dup < half >; constexpr word half_drop = gen_drop< half >; constexpr word half_zext_b = bv_zext_b < half >; constexpr word half_sext_b = bv_sext_b < half >; constexpr word half_trunc_w = bv_trunc_w< half >; constexpr word half_trunc_d = bv_trunc_d< half >; constexpr word half_add = bv_add < half >; constexpr word half_sub = bv_sub < half >; constexpr word half_mul = bv_mul < half >; constexpr word half_sdiv = bv_sdiv< half >; constexpr word half_udiv = bv_udiv< half >; constexpr word half_srem = bv_srem< half >; constexpr word half_urem = bv_urem< half >; constexpr word half_and = bv_and < half >; constexpr word half_or = bv_or < half >; constexpr word half_xor = bv_xor < half >; constexpr word half_neg = bv_neg < half >; constexpr word half_shl = bv_shl < half >; constexpr word half_lshr = bv_lshr< half >; constexpr word half_ashr = bv_ashr< half >; constexpr word half_eq = bv_eq < half >; constexpr word half_neq = bv_neq< half >; constexpr word half_ule = bv_ule< half >; constexpr word half_ult = bv_ult< half >; constexpr word half_ugt = bv_ugt< half >; constexpr word half_uge = bv_uge< half >; constexpr word half_sle = bv_sle< half >; constexpr word half_slt = bv_slt< half >; constexpr word half_sgt = bv_sgt< half >; constexpr word half_sge = bv_sge< half >; constexpr word half_guard_zero = bv_guard_zero< half >; constexpr word half_guard_nonzero = bv_guard_nonzero< half >; /* word (32 bit) operations */ constexpr word word_const = bv_const< word >; constexpr word word_zero = bv_zero < word >; constexpr word word_dup = gen_dup < word >; constexpr word word_drop = gen_drop< word >; constexpr word word_zext_b = bv_zext_b < word >; constexpr word word_zext_h = bv_zext_h < word >; constexpr word word_sext_b = bv_sext_b < word >; constexpr word word_sext_h = bv_sext_h < word >; constexpr word word_trunc_d = bv_trunc_d< word >; constexpr word word_add = bv_add < word >; constexpr word word_sub = bv_sub < word >; constexpr word word_mul = bv_mul < word >; constexpr word word_sdiv = bv_sdiv< word >; constexpr word word_udiv = bv_udiv< word >; constexpr word word_srem = bv_srem< word >; constexpr word word_urem = bv_urem< word >; constexpr word word_and = bv_and < word >; constexpr word word_or = bv_or < word >; constexpr word word_xor = bv_xor < word >; constexpr word word_neg = bv_neg < word >; constexpr word word_shl = bv_shl < word >; constexpr word word_lshr = bv_lshr< word >; constexpr word word_ashr = bv_ashr< word >; constexpr word word_eq = bv_eq < word >; constexpr word word_neq = bv_neq< word >; constexpr word word_ule = bv_ule< word >; constexpr word word_ult = bv_ult< word >; constexpr word word_ugt = bv_ugt< word >; constexpr word word_uge = bv_uge< word >; constexpr word word_sle = bv_sle< word >; constexpr word word_slt = bv_slt< word >; constexpr word word_sgt = bv_sgt< word >; constexpr word word_sge = bv_sge< word >; constexpr word word_guard_zero = bv_guard_zero< word >; constexpr word word_guard_nonzero = bv_guard_nonzero< word >; /* dyad (64 bit) operations */ constexpr word dyad_const = bv_const< dyad >; constexpr word dyad_zero = bv_zero < dyad >; constexpr word dyad_dup = gen_dup < dyad >; constexpr word dyad_drop = gen_drop< dyad >; constexpr word dyad_zext_b = bv_zext_b< dyad >; constexpr word dyad_zext_h = bv_zext_h< dyad >; constexpr word dyad_zext_w = bv_zext_w< dyad >; constexpr word dyad_sext_b = bv_sext_b< dyad >; constexpr word dyad_sext_h = bv_sext_h< dyad >; constexpr word dyad_sext_w = bv_sext_w< dyad >; constexpr word dyad_add = bv_add< dyad >; constexpr word dyad_sub = bv_sub< dyad >; constexpr word dyad_mul = bv_mul < dyad >; constexpr word dyad_sdiv = bv_sdiv< dyad >; constexpr word dyad_udiv = bv_udiv< dyad >; constexpr word dyad_srem = bv_srem< dyad >; constexpr word dyad_urem = bv_urem< dyad >; constexpr word dyad_and = bv_and< dyad >; constexpr word dyad_or = bv_or < dyad >; constexpr word dyad_xor = bv_xor< dyad >; constexpr word dyad_neg = bv_neg< dyad >; constexpr word dyad_shl = bv_shl < dyad >; constexpr word dyad_lshr = bv_lshr< dyad >; constexpr word dyad_ashr = bv_ashr< dyad >; constexpr word dyad_eq = bv_eq < dyad >; constexpr word dyad_neq = bv_neq< dyad >; constexpr word dyad_ule = bv_ule< dyad >; constexpr word dyad_ult = bv_ult< dyad >; constexpr word dyad_ugt = bv_ugt< dyad >; constexpr word dyad_uge = bv_uge< dyad >; constexpr word dyad_sle = bv_sle< dyad >; constexpr word dyad_slt = bv_slt< dyad >; constexpr word dyad_sgt = bv_sgt< dyad >; constexpr word dyad_sge = bv_sge< dyad >; constexpr word dyad_guard_zero = bv_guard_zero< dyad >; constexpr word dyad_guard_nonzero = bv_guard_nonzero< dyad >; } }