diff options
Diffstat (limited to 'target/hexagon/opcodes.c')
-rw-r--r-- | target/hexagon/opcodes.c | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/target/hexagon/opcodes.c b/target/hexagon/opcodes.c new file mode 100644 index 000000000..35d790cdd --- /dev/null +++ b/target/hexagon/opcodes.c @@ -0,0 +1,143 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * 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 <http://www.gnu.org/licenses/>. + */ + +/* + * opcodes.c + * + * data tables generated automatically + * Maybe some functions too + */ + +#include "qemu/osdep.h" +#include "attribs.h" +#include "decode.h" + +#define VEC_DESCR(A, B, C) DESCR(A, B, C) +#define DONAME(X) #X + +const char * const opcode_names[] = { +#define OPCODE(IID) DONAME(IID) +#include "opcodes_def_generated.h.inc" + NULL +#undef OPCODE +}; + +const char * const opcode_reginfo[] = { +#define IMMINFO(TAG, SIGN, SIZE, SHAMT, SIGN2, SIZE2, SHAMT2) /* nothing */ +#define REGINFO(TAG, REGINFO, RREGS, WREGS) REGINFO, +#include "op_regs_generated.h.inc" + NULL +#undef REGINFO +#undef IMMINFO +}; + + +const char * const opcode_rregs[] = { +#define IMMINFO(TAG, SIGN, SIZE, SHAMT, SIGN2, SIZE2, SHAMT2) /* nothing */ +#define REGINFO(TAG, REGINFO, RREGS, WREGS) RREGS, +#include "op_regs_generated.h.inc" + NULL +#undef REGINFO +#undef IMMINFO +}; + + +const char * const opcode_wregs[] = { +#define IMMINFO(TAG, SIGN, SIZE, SHAMT, SIGN2, SIZE2, SHAMT2) /* nothing */ +#define REGINFO(TAG, REGINFO, RREGS, WREGS) WREGS, +#include "op_regs_generated.h.inc" + NULL +#undef REGINFO +#undef IMMINFO +}; + +const char * const opcode_short_semantics[] = { +#define DEF_SHORTCODE(TAG, SHORTCODE) [TAG] = #SHORTCODE, +#include "shortcode_generated.h.inc" +#undef DEF_SHORTCODE + NULL +}; + +DECLARE_BITMAP(opcode_attribs[XX_LAST_OPCODE], A_ZZ_LASTATTRIB); + +static void init_attribs(int tag, ...) +{ + va_list ap; + int attr; + va_start(ap, tag); + while ((attr = va_arg(ap, int)) != 0) { + set_bit(attr, opcode_attribs[tag]); + } + va_end(ap); +} + +const OpcodeEncoding opcode_encodings[] = { +#define DEF_ENC32(OPCODE, ENCSTR) \ + [OPCODE] = { .encoding = ENCSTR }, + +#define DEF_ENC_SUBINSN(OPCODE, CLASS, ENCSTR) \ + [OPCODE] = { .encoding = ENCSTR, .enc_class = CLASS }, + +#define DEF_EXT_ENC(OPCODE, CLASS, ENCSTR) \ + [OPCODE] = { .encoding = ENCSTR, .enc_class = CLASS }, + +#include "imported/encode.def" + +#undef DEF_ENC32 +#undef DEF_ENC_SUBINSN +#undef DEF_EXT_ENC +}; + +void opcode_init(void) +{ + init_attribs(0, 0); + +#define ATTRIBS(...) , ## __VA_ARGS__, 0 +#define OP_ATTRIB(TAG, ARGS) init_attribs(TAG ARGS); +#include "op_attribs_generated.h.inc" +#undef OP_ATTRIB +#undef ATTRIBS + + decode_init(); +} + + +#define NEEDLE "IMMEXT(" + +int opcode_which_immediate_is_extended(Opcode opcode) +{ + const char *p; + + g_assert(opcode < XX_LAST_OPCODE); + g_assert(GET_ATTRIB(opcode, A_EXTENDABLE)); + + p = opcode_short_semantics[opcode]; + p = strstr(p, NEEDLE); + g_assert(p); + p += strlen(NEEDLE); + while (isspace(*p)) { + p++; + } + /* lower is always imm 0, upper always imm 1. */ + if (islower(*p)) { + return 0; + } else if (isupper(*p)) { + return 1; + } else { + g_assert_not_reached(); + } +} |