📄 bfin-dis.c
字号:
/* * Copyright (c) 2000, 2001 Analog Devices Inc. * Copyright (c) 2003 Metrowerks * */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <signal.h>#include "opcode/bfin.h"#define M_S2RND 1#define M_T 2#define M_W32 3#define M_FU 4#define M_TFU 6#define M_IS 8#define M_ISS2 9#define M_IH 11#define M_IU 12#ifndef PRINTF#define PRINTF printf#endif#ifndef EXIT#define EXIT skyeye_exit#endiftypedef int TIword;#define HOST_LONG_WORD_SIZE (sizeof(long)*8)#define XFIELD(w,p,s) (((w)&((1<<(s))-1)<<(p))>>(p))#define SIGNEXTEND(v, n) (((bs32)v << (HOST_LONG_WORD_SIZE - (n))) >> (HOST_LONG_WORD_SIZE - (n)))#include "bfin-sim.h"#include "iomem.h"/* For dealing with parallel instructions, we must avoid changing our register file until all parallel insns have been simulated. This queue of stores can be used to delay a modification. @@@ Should go and convert all 32 bit insns to use this. */struct store{ bu32 *addr; bu32 val;};struct store stores[10];int n_stores;#define STORE(X,Y) do { \ stores[n_stores].addr = &(X); \ stores[n_stores++].val = (Y); \ } while (0)static __attribute__ ((noreturn)) void unhandled_instruction (void){ printf ("\nolderpc=%x,oldpc=%x\n,pc=0x%x,iw0=0x%x,iw1=0x%x\n", OLDERPCREG, OLDPCREG, PCREG, get_word (saved_state.memory, PCREG), get_word (saved_state.memory, PCREG + 2)); raise (SIGILL); fprintf (stderr, "unhandled instruction ... aborting\n"); abort ();}static voidsetflags_nz (bu32 val){ saved_state.az = val == 0; saved_state.an = val >> 31;}static voidsetflags_logical (bu32 val){ setflags_nz (val); saved_state.ac0 = 0; saved_state.v = 0;}static bu32ashiftrt (bu32 val, int cnt){ int real_cnt = cnt > 32 ? 32 : cnt; bu32 sgn = ~((val >> 31) - 1); int sgncnt = 32 - real_cnt; if (sgncnt > 16) sgn <<= 16, sgncnt -= 16; sgn <<= sgncnt; if (real_cnt > 16) val >>= 16, real_cnt -= 16; val >>= real_cnt; val |= sgn; saved_state.an = val >> 31; saved_state.az = val == 0; /* @@@ */ saved_state.v = 0; return val;}static bu32lshiftrt (bu32 val, int cnt){ int real_cnt = cnt > 32 ? 32 : cnt; if (real_cnt > 16) val >>= 16, real_cnt -= 16; val >>= real_cnt; saved_state.an = val >> 31; saved_state.az = val == 0; saved_state.v = 0; return val;}static bu32lshift (bu32 val, int cnt){ int real_cnt = cnt > 32 ? 32 : cnt; if (real_cnt > 16) val <<= 16, real_cnt -= 16; val <<= real_cnt; saved_state.an = val >> 31; saved_state.az = val == 0; saved_state.v = 0; return val;}static bu32add32 (bu32 a, bu32 b, int carry){ int flgs = a >> 31; int flgo = b >> 31; bu32 v = a + b; int flgn = v >> 31; int overflow = (flgs ^ flgn) & (flgo ^ flgn); saved_state.an = flgn; saved_state.vs |= overflow; saved_state.v = overflow; saved_state.v_internal |= overflow; saved_state.az = v == 0; if (carry) saved_state.ac0 = ~a < b; return v;}static bu32sub32 (bu32 a, bu32 b, int carry){ int flgs = a >> 31; int flgo = b >> 31; bu32 v = a - b; int flgn = v >> 31; int overflow = (flgs ^ flgo) & (flgn ^ flgs); saved_state.an = flgn; saved_state.vs |= overflow; saved_state.v = overflow; saved_state.v_internal |= overflow; saved_state.az = v == 0; if (carry) saved_state.ac0 = b <= a; return v;}static bu32min32 (bu32 a, bu32 b){ int val = a; if ((bs32) a > (bs32) b) val = b; setflags_nz (val); saved_state.v = 0; return val;}static bu32max32 (bu32 a, bu32 b){ int val = a; if ((bs32) a < (bs32) b) val = b; setflags_nz (val); saved_state.v = 0; return val;}static bu32add_and_shift (bu32 a, bu32 b, int shift){ int v; saved_state.v_internal = 0; v = add32 (a, b, 0); while (shift-- > 0) { int x = v >> 30; if (x == 1 || x == 2) saved_state.v_internal = 1; v <<= 1; } saved_state.v = saved_state.v_internal; saved_state.vs |= saved_state.v; return v;}typedef enum{ c_0, c_1, c_4, c_2, c_uimm2, c_uimm3, c_imm3, c_pcrel4, c_imm4, c_uimm4s4, c_uimm4, c_uimm4s2, c_negimm5s4, c_imm5, c_uimm5, c_imm6, c_imm7, c_imm8, c_uimm8, c_pcrel8, c_uimm8s4, c_pcrel8s4, c_lppcrel10, c_pcrel10, c_pcrel12, c_imm16s4, c_luimm16, c_imm16, c_huimm16, c_rimm16, c_imm16s2, c_uimm16s4, c_uimm16, c_pcrel24,} const_forms_t;static struct{ char *name; int nbits; char reloc; char issigned; char pcrel; char scale; char offset; char negative; char positive;} constant_formats[] = { { "0", 0, 0, 1, 0, 0, 0, 0, 0}, { "1", 0, 0, 1, 0, 0, 0, 0, 0}, { "4", 0, 0, 1, 0, 0, 0, 0, 0}, { "2", 0, 0, 1, 0, 0, 0, 0, 0}, { "uimm2", 2, 0, 0, 0, 0, 0, 0, 0}, { "uimm3", 3, 0, 0, 0, 0, 0, 0, 0}, { "imm3", 3, 0, 1, 0, 0, 0, 0, 0}, { "pcrel4", 4, 1, 0, 1, 1, 0, 0, 0}, { "imm4", 4, 0, 1, 0, 0, 0, 0, 0}, { "uimm4s4", 4, 0, 0, 0, 2, 0, 0, 1}, { "uimm4", 4, 0, 0, 0, 0, 0, 0, 0}, { "uimm4s2", 4, 0, 0, 0, 1, 0, 0, 1}, { "negimm5s4", 5, 0, 1, 0, 2, 0, 1, 0}, { "imm5", 5, 0, 1, 0, 0, 0, 0, 0}, { "uimm5", 5, 0, 0, 0, 0, 0, 0, 0}, { "imm6", 6, 0, 1, 0, 0, 0, 0, 0}, { "imm7", 7, 0, 1, 0, 0, 0, 0, 0}, { "imm8", 8, 0, 1, 0, 0, 0, 0, 0}, { "uimm8", 8, 0, 0, 0, 0, 0, 0, 0}, { "pcrel8", 8, 1, 0, 1, 1, 0, 0, 0}, { "uimm8s4", 8, 0, 0, 0, 2, 0, 0, 0}, { "pcrel8s4", 8, 1, 1, 1, 2, 0, 0, 0}, { "lppcrel10", 10, 1, 0, 1, 1, 0, 0, 0}, { "pcrel10", 10, 1, 1, 1, 1, 0, 0, 0}, { "pcrel12", 12, 1, 1, 1, 1, 0, 0, 0}, { "imm16s4", 16, 0, 1, 0, 2, 0, 0, 0}, { "luimm16", 16, 1, 0, 0, 0, 0, 0, 0}, { "imm16", 16, 0, 1, 0, 0, 0, 0, 0}, { "huimm16", 16, 1, 0, 0, 0, 0, 0, 0}, { "rimm16", 16, 1, 1, 0, 0, 0, 0, 0}, { "imm16s2", 16, 0, 1, 0, 1, 0, 0, 0}, { "uimm16s4", 16, 0, 0, 0, 2, 0, 0, 0}, { "uimm16", 16, 0, 0, 0, 0, 0, 0, 0}, {"pcrel24", 24, 1, 1, 1, 1, 0, 0, 0},};static bu32fmtconst (const_forms_t cf, bu32 x, bu32 pc){ if (0 && constant_formats[cf].reloc) { bu32 ea = (((constant_formats[cf].pcrel ? SIGNEXTEND (x, constant_formats[cf].nbits) : x) + constant_formats[cf].offset) << constant_formats[cf].scale); if (constant_formats[cf].pcrel) ea += pc; // outf->print_address_func (ea, outf); return ea; } /* negative constants have an implied sign bit */ if (constant_formats[cf].negative) { int nb = constant_formats[cf].nbits + 1; x = x | (1 << constant_formats[cf].nbits); x = SIGNEXTEND (x, nb); } else if (constant_formats[cf].issigned) x = SIGNEXTEND (x, constant_formats[cf].nbits); x += constant_formats[cf].offset; x <<= constant_formats[cf].scale; return x;}#undef SIGNEXTEND#undef HOST_LONG_WORD_SIZE#define HOST_LONG_WORD_SIZE (sizeof(int)*8)#define SIGNEXTEND(v, n) (((long)(v) << (HOST_LONG_WORD_SIZE - (n))) >> (HOST_LONG_WORD_SIZE - (n)))enum machine_registers{ REG_RL0, REG_RL1, REG_RL2, REG_RL3, REG_RL4, REG_RL5, REG_RL6, REG_RL7, REG_RH0, REG_RH1, REG_RH2, REG_RH3, REG_RH4, REG_RH5, REG_RH6, REG_RH7, REG_R0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7, REG_R1_0, REG_R3_2, REG_R5_4, REG_R7_6, REG_P0, REG_P1, REG_P2, REG_P3, REG_P4, REG_P5, REG_SP, REG_FP, REG_A0x, REG_A1x, REG_A0w, REG_A1w, REG_A0, REG_A1, REG_I0, REG_I1, REG_I2, REG_I3, REG_M0, REG_M1, REG_M2, REG_M3, REG_B0, REG_B1, REG_B2, REG_B3, REG_L0, REG_L1, REG_L2, REG_L3, REG_AZ, REG_AN, REG_AC, REG_AV0, REG_AV1, REG_AQ, REG_sftreset, REG_omode, REG_excause, REG_emucause, REG_idle_req, REG_hwerrcause, REG_CC, REG_LC0, REG_LC1, REG_GP, REG_ASTAT, REG_RETS, REG_LT0, REG_LB0, REG_LT1, REG_LB1, REG_CYCLES, REG_CYCLES2, REG_USP, REG_SEQSTAT, REG_SYSCFG, REG_RETI, REG_RETX, REG_RETN, REG_RETE, REG_BR0, REG_BR1, REG_BR2, REG_BR3, REG_BR4, REG_BR5, REG_BR6, REG_BR7, REG_PL0, REG_PL1, REG_PL2, REG_PL3, REG_PL4, REG_PL5, REG_SLP, REG_FLP, REG_PH0, REG_PH1, REG_PH2, REG_PH3, REG_PH4, REG_PH5, REG_SHP, REG_FHP, REG_IL0, REG_IL1, REG_IL2, REG_IL3, REG_ML0, REG_ML1, REG_ML2, REG_ML3, REG_BL0, REG_BL1, REG_BL2, REG_BL3, REG_LL0, REG_LL1, REG_LL2, REG_LL3, REG_IH0, REG_IH1, REG_IH2, REG_IH3, REG_MH0, REG_MH1, REG_MH2, REG_MH3, REG_BH0, REG_BH1, REG_BH2, REG_BH3, REG_LH0, REG_LH1, REG_LH2, REG_LH3, REG_LASTREG,};enum reg_class{ rc_dregs_lo, rc_dregs_hi, rc_dregs, rc_dregs_pair, rc_pregs, rc_spfp, rc_dregs_hilo, rc_accum_ext, rc_accum_word, rc_accum, rc_iregs, rc_mregs, rc_bregs, rc_lregs, rc_dpregs, rc_gregs, rc_regs, rc_statbits, rc_ignore_bits, rc_ccstat, rc_counters, rc_dregs2_sysregs1, rc_open, rc_sysregs2, rc_sysregs3, rc_allregs, LIM_REG_CLASSES};static char *reg_names[] = { "R0.L", "R1.L", "R2.L", "R3.L", "R4.L", "R5.L", "R6.L", "R7.L", "R0.H", "R1.H", "R2.H", "R3.H", "R4.H", "R5.H", "R6.H", "R7.H", "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R1:0", "R3:2", "R5:4", "R7:6", "P0", "P1", "P2", "P3", "P4", "P5", "SP", "FP", "A0.x", "A1.x", "A0.w", "A1.w", "A0", "A1", "I0", "I1", "I2", "I3", "M0", "M1", "M2", "M3", "B0", "B1", "B2", "B3", "L0", "L1", "L2", "L3", "AZ", "AN", "AC", "AV0", "AV1", "AQ", "sftreset", "omode", "excause", "emucause", "idle_req", "hwerrcause", "CC", "LC0", "LC1", "GP", "ASTAT", "RETS", "LT0", "LB0", "LT1", "LB1", "CYCLES", "CYCLES2", "USP", "SEQSTAT", "SYSCFG", "RETI", "RETX", "RETN", "RETE", "R0.B", "R1.B", "R2.B", "R3.B", "R4.B", "R5.B", "R6.B", "R7.B", "P0.L", "P1.L", "P2.L", "P3.L", "P4.L", "P5.L", "SP.L", "FP.L", "P0.H", "P1.H", "P2.H", "P3.H", "P4.H", "P5.H", "SP.H", "FP.H", "I0.L", "I1.L", "I2.L", "I3.L", "M0.L", "M1.L", "M2.L", "M3.L", "B0.L", "B1.L", "B2.L", "B3.L", "L0.L", "L1.L", "L2.L", "L3.L", "I0.H", "I1.H", "I2.H", "I3.H", "M0.H", "M1.H", "M2.H", "M3.H", "B0.H", "B1.H", "B2.H", "B3.H", "L0.H", "L1.H", "L2.H", "L3.H", "LASTREG", 0};#define REGNAME(x) ((x) < REG_LASTREG ? (reg_names[x]) : "...... Illegal register .......")/* RL(0..7) */static enum machine_registers decode_dregs_lo[] = { REG_RL0, REG_RL1, REG_RL2, REG_RL3, REG_RL4, REG_RL5, REG_RL6, REG_RL7,};#define dregs_lo(x) REGNAME(decode_dregs_lo[(x) & 7])/* RH(0..7) */static enum machine_registers decode_dregs_hi[] = { REG_RH0, REG_RH1, REG_RH2, REG_RH3, REG_RH4, REG_RH5, REG_RH6, REG_RH7,};#define dregs_hi(x) REGNAME(decode_dregs_hi[(x) & 7])/* R(0..7) */static enum machine_registers decode_dregs[] = { REG_R0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7,};#define dregs(x) REGNAME(decode_dregs[(x) & 7])/* R BYTE(0..7) */static enum machine_registers decode_dregs_byte[] = { REG_BR0, REG_BR1, REG_BR2, REG_BR3, REG_BR4, REG_BR5, REG_BR6, REG_BR7,};#define dregs_byte(x) REGNAME(decode_dregs_byte[(x) & 7])/* R1:0 - R3:2 - R5:4 - R7:6 - */static enum machine_registers decode_dregs_pair[] = { REG_R1_0, REG_LASTREG, REG_R3_2, REG_LASTREG, REG_R5_4, REG_LASTREG, REG_R7_6, REG_LASTREG,};#define dregs_pair(x) REGNAME(decode_dregs_pair[(x) & 7])/* P(0..5) SP FP */static enum machine_registers decode_pregs[] = { REG_P0, REG_P1, REG_P2, REG_P3, REG_P4, REG_P5, REG_SP, REG_FP,};#define pregs(x) REGNAME(decode_pregs[(x) & 7])/* SP FP */static enum machine_registers decode_spfp[] = { REG_SP, REG_FP,};#define spfp(x) REGNAME(decode_spfp[(x) & 1])/* [dregs_lo dregs_hi] */static enum machine_registers decode_dregs_hilo[] = { REG_RL0, REG_RL1, REG_RL2, REG_RL3, REG_RL4, REG_RL5, REG_RL6, REG_RL7, REG_RH0, REG_RH1, REG_RH2, REG_RH3, REG_RH4, REG_RH5, REG_RH6, REG_RH7,};#define dregs_hilo(x,i) REGNAME(decode_dregs_hilo[((i)<<3)|x])/* A0x A1x */static enum machine_registers decode_accum_ext[] = { REG_A0x, REG_A1x,};#define accum_ext(x) REGNAME(decode_accum_ext[(x) & 1])/* A0w A1w */static enum machine_registers decode_accum_word[] = { REG_A0w, REG_A1w,};#define accum_word(x) REGNAME(decode_accum_word[(x) & 1])/* A0 A1 */static enum machine_registers decode_accum[] = { REG_A0, REG_A1,};#define accum(x) REGNAME(decode_accum[(x) & 1])/* I(0..3) */static enum machine_registers decode_iregs[] = { REG_I0, REG_I1, REG_I2, REG_I3,};#define iregs(x) REGNAME(decode_iregs[(x) & 3])/* M(0..3) */static enum machine_registers decode_mregs[] = { REG_M0, REG_M1, REG_M2, REG_M3,};#define mregs(x) REGNAME(decode_mregs[(x) & 3])/* B(0..3) */static enum machine_registers decode_bregs[] = { REG_B0, REG_B1, REG_B2, REG_B3,};#define bregs(x) REGNAME(decode_bregs[(x) & 3])/* L(0..3) */static enum machine_registers decode_lregs[] = { REG_L0, REG_L1, REG_L2, REG_L3,};#define lregs(x) REGNAME(decode_lregs[(x) & 3])/* dregs pregs */static enum machine_registers decode_dpregs[] = { REG_R0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7, REG_P0, REG_P1, REG_P2, REG_P3, REG_P4, REG_P5, REG_SP, REG_FP,};#define dpregs(x) REGNAME(decode_dpregs[(x) & 15])/* [dregs pregs] */static enum machine_registers decode_gregs[] = { REG_R0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7, REG_P0, REG_P1, REG_P2, REG_P3, REG_P4, REG_P5, REG_SP, REG_FP,};#define gregs(x,i) REGNAME(decode_gregs[((i)<<3)|x])/* [dregs pregs (iregs mregs) (bregs lregs)] */static enum machine_registers decode_regs[] = { REG_R0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7, REG_P0, REG_P1, REG_P2, REG_P3, REG_P4, REG_P5, REG_SP, REG_FP, REG_I0, REG_I1, REG_I2, REG_I3, REG_M0, REG_M1, REG_M2, REG_M3, REG_B0, REG_B1, REG_B2, REG_B3, REG_L0, REG_L1, REG_L2, REG_L3,};#define regs(x,i) REGNAME(decode_regs[((i)<<3)|x])/* [dregs pregs (iregs mregs) (bregs lregs) Low Half] */static enum machine_registers decode_regs_lo[] = { REG_RL0, REG_RL1, REG_RL2, REG_RL3, REG_RL4, REG_RL5, REG_RL6, REG_RL7, REG_PL0, REG_PL1, REG_PL2, REG_PL3, REG_PL4, REG_PL5, REG_SLP, REG_FLP, REG_IL0, REG_IL1, REG_IL2, REG_IL3, REG_ML0, REG_ML1, REG_ML2, REG_ML3, REG_BL0, REG_BL1, REG_BL2, REG_BL3, REG_LL0, REG_LL1, REG_LL2, REG_LL3,};#define regs_lo(x,i) REGNAME(decode_regs_lo[((i)<<3)|x])/* [dregs pregs (iregs mregs) (bregs lregs) High Half] */static enum machine_registers decode_regs_hi[] = { REG_RH0, REG_RH1, REG_RH2, REG_RH3, REG_RH4, REG_RH5, REG_RH6, REG_RH7, REG_PH0, REG_PH1, REG_PH2, REG_PH3, REG_PH4, REG_PH5, REG_SHP, REG_FHP, REG_IH0, REG_IH1, REG_IH2, REG_IH3, REG_MH0, REG_MH1, REG_LH2, REG_MH3, REG_BH0, REG_BH1, REG_BH2, REG_BH3, REG_LH0, REG_LH1, REG_LH2, REG_LH3,};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -