diff options
author | Michael Walle <michael@walle.cc> | 2011-03-07 23:01:04 +0100 |
---|---|---|
committer | Edgar E. Iglesias <edgar.iglesias@gmail.com> | 2011-03-31 08:54:05 +0200 |
commit | a5086f95421e43c7b9e1b28a111aae0be4848117 (patch) | |
tree | 086c0e1019960a732aa6d9559afe6c5b4dff59d9 | |
parent | fcda98630b121a63c9de0705df02e59f4dc2fecc (diff) |
lm32: use lookup table for opcodes
Instead of a for loop use a faster lookup table.
Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
-rw-r--r-- | target-lm32/lm32-decode.h | 78 | ||||
-rw-r--r-- | target-lm32/translate.c | 80 |
2 files changed, 18 insertions, 140 deletions
diff --git a/target-lm32/lm32-decode.h b/target-lm32/lm32-decode.h deleted file mode 100644 index 42205d931..000000000 --- a/target-lm32/lm32-decode.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * LatticeMico32 instruction decoding macros. - * - * Copyright (c) 2010 Michael Walle <michael@walle.cc> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* Convenient binary macros */ -#define HEX__(n) 0x##n##LU -#define B8__(x) (((x&0x0000000FLU) ? 1 : 0) \ - + ((x&0x000000F0LU) ? 2 : 0) \ - + ((x&0x00000F00LU) ? 4 : 0) \ - + ((x&0x0000F000LU) ? 8 : 0) \ - + ((x&0x000F0000LU) ? 16 : 0) \ - + ((x&0x00F00000LU) ? 32 : 0) \ - + ((x&0x0F000000LU) ? 64 : 0) \ - + ((x&0xF0000000LU) ? 128 : 0)) -#define B8(d) ((unsigned char)B8__(HEX__(d))) - -/* Decode logic, value and mask. */ -#define DEC_ADD {B8(00001101), B8(00011111)} -#define DEC_AND {B8(00001000), B8(00011111)} -#define DEC_ANDHI {B8(00011000), B8(00111111)} -#define DEC_B {B8(00110000), B8(00111111)} -#define DEC_BI {B8(00111000), B8(00111111)} -#define DEC_BE {B8(00010001), B8(00111111)} -#define DEC_BG {B8(00010010), B8(00111111)} -#define DEC_BGE {B8(00010011), B8(00111111)} -#define DEC_BGEU {B8(00010100), B8(00111111)} -#define DEC_BGU {B8(00010101), B8(00111111)} -#define DEC_BNE {B8(00010111), B8(00111111)} -#define DEC_CALL {B8(00110110), B8(00111111)} -#define DEC_CALLI {B8(00111110), B8(00111111)} -#define DEC_CMPE {B8(00011001), B8(00011111)} -#define DEC_CMPG {B8(00011010), B8(00011111)} -#define DEC_CMPGE {B8(00011011), B8(00011111)} -#define DEC_CMPGEU {B8(00011100), B8(00011111)} -#define DEC_CMPGU {B8(00011101), B8(00011111)} -#define DEC_CMPNE {B8(00011111), B8(00011111)} -#define DEC_DIVU {B8(00100011), B8(00111111)} -#define DEC_LB {B8(00000100), B8(00111111)} -#define DEC_LBU {B8(00010000), B8(00111111)} -#define DEC_LH {B8(00000111), B8(00111111)} -#define DEC_LHU {B8(00001011), B8(00111111)} -#define DEC_LW {B8(00001010), B8(00111111)} -#define DEC_MODU {B8(00110001), B8(00111111)} -#define DEC_MUL {B8(00000010), B8(00011111)} -#define DEC_NOR {B8(00000001), B8(00011111)} -#define DEC_OR {B8(00001110), B8(00011111)} -#define DEC_ORHI {B8(00011110), B8(00111111)} -#define DEC_SCALL {B8(00101011), B8(00111111)} -#define DEC_RCSR {B8(00100100), B8(00111111)} -#define DEC_SB {B8(00001100), B8(00111111)} -#define DEC_SEXTB {B8(00101100), B8(00111111)} -#define DEC_SEXTH {B8(00110111), B8(00111111)} -#define DEC_SH {B8(00000011), B8(00111111)} -#define DEC_SL {B8(00001111), B8(00011111)} -#define DEC_SR {B8(00000101), B8(00011111)} -#define DEC_SRU {B8(00000000), B8(00011111)} -#define DEC_SUB {B8(00110010), B8(00111111)} -#define DEC_SW {B8(00010110), B8(00111111)} -#define DEC_USER {B8(00110011), B8(00111111)} -#define DEC_WCSR {B8(00110100), B8(00111111)} -#define DEC_XNOR {B8(00001001), B8(00011111)} -#define DEC_XOR {B8(00000110), B8(00011111)} - diff --git a/target-lm32/translate.c b/target-lm32/translate.c index aa08a142e..666d5f4dc 100644 --- a/target-lm32/translate.c +++ b/target-lm32/translate.c @@ -29,7 +29,6 @@ #include "disas.h" #include "helper.h" #include "tcg-op.h" -#include "lm32-decode.h" #include "qemu-common.h" #include "hw/lm32_pic.h" @@ -963,66 +962,28 @@ static void dec_xor(DisasContext *dc) } } -typedef struct { - struct { - uint32_t bits; - uint32_t mask; - }; - void (*dec)(DisasContext *dc); -} DecoderInfo; +static void dec_ill(DisasContext *dc) +{ + cpu_abort(dc->env, "unknown opcode 0x%02x\n", dc->opcode); +} +typedef void (*DecoderInfo)(DisasContext *dc); static const DecoderInfo decinfo[] = { - {DEC_ADD, dec_add}, - {DEC_AND, dec_and}, - {DEC_ANDHI, dec_andhi}, - {DEC_B, dec_b}, - {DEC_BI, dec_bi}, - {DEC_BE, dec_be}, - {DEC_BG, dec_bg}, - {DEC_BGE, dec_bge}, - {DEC_BGEU, dec_bgeu}, - {DEC_BGU, dec_bgu}, - {DEC_BNE, dec_bne}, - {DEC_CALL, dec_call}, - {DEC_CALLI, dec_calli}, - {DEC_CMPE, dec_cmpe}, - {DEC_CMPG, dec_cmpg}, - {DEC_CMPGE, dec_cmpge}, - {DEC_CMPGEU, dec_cmpgeu}, - {DEC_CMPGU, dec_cmpgu}, - {DEC_CMPNE, dec_cmpne}, - {DEC_DIVU, dec_divu}, - {DEC_LB, dec_lb}, - {DEC_LBU, dec_lbu}, - {DEC_LH, dec_lh}, - {DEC_LHU, dec_lhu}, - {DEC_LW, dec_lw}, - {DEC_MODU, dec_modu}, - {DEC_MUL, dec_mul}, - {DEC_NOR, dec_nor}, - {DEC_OR, dec_or}, - {DEC_ORHI, dec_orhi}, - {DEC_SCALL, dec_scall}, - {DEC_RCSR, dec_rcsr}, - {DEC_SB, dec_sb}, - {DEC_SEXTB, dec_sextb}, - {DEC_SEXTH, dec_sexth}, - {DEC_SH, dec_sh}, - {DEC_SL, dec_sl}, - {DEC_SR, dec_sr}, - {DEC_SRU, dec_sru}, - {DEC_SUB, dec_sub}, - {DEC_SW, dec_sw}, - {DEC_USER, dec_user}, - {DEC_WCSR, dec_wcsr}, - {DEC_XNOR, dec_xnor}, - {DEC_XOR, dec_xor}, + dec_sru, dec_nor, dec_mul, dec_sh, dec_lb, dec_sr, dec_xor, dec_lh, + dec_and, dec_xnor, dec_lw, dec_lhu, dec_sb, dec_add, dec_or, dec_sl, + dec_lbu, dec_be, dec_bg, dec_bge, dec_bgeu, dec_bgu, dec_sw, dec_bne, + dec_andhi, dec_cmpe, dec_cmpg, dec_cmpge, dec_cmpgeu, dec_cmpgu, dec_orhi, + dec_cmpne, + dec_sru, dec_nor, dec_mul, dec_divu, dec_rcsr, dec_sr, dec_xor, dec_ill, + dec_and, dec_xnor, dec_ill, dec_scall, dec_sextb, dec_add, dec_or, dec_sl, + dec_b, dec_modu, dec_sub, dec_user, dec_wcsr, dec_ill, dec_call, dec_sexth, + dec_bi, dec_cmpe, dec_cmpg, dec_cmpge, dec_cmpgeu, dec_cmpgu, dec_calli, + dec_cmpne }; static inline void decode(DisasContext *dc) { uint32_t ir; - int i; if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) { tcg_gen_debug_insn_start(dc->pc); @@ -1061,15 +1022,10 @@ static inline void decode(DisasContext *dc) dc->format = OP_FMT_RI; } - /* Large switch for all insns. */ - for (i = 0; i < ARRAY_SIZE(decinfo); i++) { - if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits) { - decinfo[i].dec(dc); - return; - } - } + assert(ARRAY_SIZE(decinfo) == 64); + assert(dc->opcode < 64); - cpu_abort(dc->env, "unknown opcode 0x%02x\n", dc->opcode); + decinfo[dc->opcode](dc); } static void check_breakpoint(CPUState *env, DisasContext *dc) |