disas: import disassmebler from binutils
This commit is contained in:
parent
8c78e941dd
commit
c42af9ff35
2
disas.c
2
disas.c
|
@ -201,6 +201,8 @@ static void initialize_debug_host(CPUDebug *s)
|
|||
s->info.cap_insn_split = 6;
|
||||
#elif defined(__hppa__)
|
||||
s->info.print_insn = print_insn_hppa;
|
||||
#elif defined(__e2k__)
|
||||
s->info.print_insn = print_insn_e2k;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,556 @@
|
|||
|
||||
#include <sys/types.h>
|
||||
|
||||
#define COMMON_PART \
|
||||
const char *name; \
|
||||
int (* parse_args) (char **, const struct e2k_opcode_templ *); \
|
||||
const char * (* merge) (struct e2k_opcode_templ *, const struct e2k_opcode_templ *)
|
||||
|
||||
#define ALOPF1 1
|
||||
#define ALOPF2 2
|
||||
#define ALOPF3 3
|
||||
#define ALOPF7 4
|
||||
#define ALOPF8 5
|
||||
#define ALOPF10 6
|
||||
#define ALOPF11 7
|
||||
#define ALOPF11_LIT8 8
|
||||
#define ALOPF11_MERGE 9
|
||||
#define ALOPF12 10
|
||||
#define ALOPF12_PSHUFH 11
|
||||
#define ALOPF12_IBRANCHD 12
|
||||
#define ALOPF12_ICALLD 13
|
||||
#define ALOPF13 14
|
||||
#define ALOPF15 15
|
||||
#define ALOPF16 16
|
||||
#define ALOPF21 17
|
||||
#define ALOPF21_MERGE 18
|
||||
#define ALOPF22 19
|
||||
#define MERGE 20
|
||||
#define MMURR 21
|
||||
#define MMURW 22
|
||||
#define AAURR 23
|
||||
#define AAURW 24
|
||||
#define ALOPF17 25
|
||||
|
||||
#define ALF_PART \
|
||||
u_int8_t alopf; \
|
||||
int need_mas; \
|
||||
u_int8_t opc; \
|
||||
int allowed_channels[6]
|
||||
|
||||
|
||||
#define MAS 1
|
||||
#define NO_MAS 0
|
||||
|
||||
/* ALES.opc2 values. See B.1.2 in iset.single. */
|
||||
#define EXT 0x1
|
||||
#define EXT1 0x2
|
||||
#define EXT2 0x3
|
||||
#define FLB 0x4
|
||||
#define FLH 0x5
|
||||
#define FLW 0x6
|
||||
#define FLD 0x7
|
||||
#define ICMB0 0x8
|
||||
#define ICMB1 0x9
|
||||
#define ICMB2 0xA
|
||||
#define ICMB3 0xB
|
||||
|
||||
#define FCMB0 0xC
|
||||
#define FCMB1 0xD
|
||||
#define PFCMB0 0XE
|
||||
#define PFCMB1 0xF
|
||||
#define LCMBD0 0x10
|
||||
#define LCMBD1 0x11
|
||||
#define LCMBQ0 0x12
|
||||
#define LCMBQ1 0x13
|
||||
#define QPFCMB0 0x16
|
||||
#define QPFCMB1 0x17
|
||||
|
||||
|
||||
/* ALES.opce values. */
|
||||
#define NONE 0xc0
|
||||
|
||||
|
||||
/* It seems that LAS doesn't support %xr's, that's
|
||||
why everywhere where an x-args is supposed we
|
||||
use a d-one. */
|
||||
typedef enum {
|
||||
SINGLE,
|
||||
DOUBLE,
|
||||
QUAD,
|
||||
QPACKED
|
||||
} e2k_register_format;
|
||||
|
||||
|
||||
#define ARGS_S SINGLE
|
||||
#define ARGS_D DOUBLE
|
||||
#define ARGS_Q QUAD
|
||||
#define ARGS_P QPACKED
|
||||
|
||||
#define ARGS_SS {SINGLE, SINGLE}
|
||||
#define ARGS_SD {SINGLE, DOUBLE}
|
||||
#define ARGS_SQ {SINGLE, QUAD}
|
||||
#define ARGS_DS {DOUBLE, SINGLE}
|
||||
#define ARGS_DD {DOUBLE, DOUBLE}
|
||||
#define ARGS_DQ {DOUBLE, QUAD}
|
||||
#define ARGS_DP {DOUBLE, QPACKED}
|
||||
#define ARGS_QS {QUAD, SINGLE}
|
||||
#define ARGS_PS {QPACKED, SINGLE}
|
||||
#define ARGS_QD {QUAD, DOUBLE}
|
||||
#define ARGS_PD {QPACKED, DOUBLE}
|
||||
#define ARGS_QQ {QUAD, QUAD}
|
||||
#define ARGS_PP {QPACKED, QPACKED}
|
||||
|
||||
#define ARGS_SSS {SINGLE, SINGLE, SINGLE}
|
||||
#define ARGS_SSD {SINGLE, SINGLE, DOUBLE}
|
||||
#define ARGS_SSQ {SINGLE, SINGLE, QUAD}
|
||||
#define ARGS_SSP {SINGLE, SINGLE, QPACKED}
|
||||
#define ARGS_SDD {SINGLE, DOUBLE, DOUBLE}
|
||||
#define ARGS_DSS {DOUBLE, SINGLE, SINGLE}
|
||||
#define ARGS_DSD {DOUBLE, SINGLE, DOUBLE}
|
||||
#define ARGS_DDS {DOUBLE, DOUBLE, SINGLE}
|
||||
#define ARGS_DDD {DOUBLE, DOUBLE, DOUBLE}
|
||||
#define ARGS_DDQ {DOUBLE, DOUBLE, QUAD}
|
||||
#define ARGS_DDP {DOUBLE, DOUBLE, QPACKED}
|
||||
#define ARGS_DQQ {DOUBLE, QUAD, QUAD}
|
||||
#define ARGS_DPP {DOUBLE, QPACKED, QPACKED}
|
||||
#define ARGS_QSS {QUAD, SINGLE, SINGLE}
|
||||
#define ARGS_QSD {QUAD, SINGLE, DOUBLE}
|
||||
#define ARGS_QSQ {QUAD, SINGLE, QUAD}
|
||||
#define ARGS_PSP {QPACKED, SINGLE, QPACKED}
|
||||
#define ARGS_QSP {QUAD, SINGLE, QPACKED}
|
||||
#define ARGS_QDQ {QUAD, DOUBLE, QUAD}
|
||||
#define ARGS_PDP {QPACKED, DOUBLE, QPACKED}
|
||||
#define ARGS_QQD {QUAD, QUAD, DOUBLE}
|
||||
#define ARGS_PPD {QPACKED, QPACKED, DOUBLE}
|
||||
#define ARGS_QQQ {QUAD, QUAD, QUAD}
|
||||
#define ARGS_PPP {QPACKED, QPACKED, QPACKED}
|
||||
|
||||
#define ARGS_SSSS {SINGLE, SINGLE, SINGLE, SINGLE}
|
||||
#define ARGS_DDSD {DOUBLE, DOUBLE, SINGLE, DOUBLE}
|
||||
#define ARGS_DDDD {DOUBLE, DOUBLE, DOUBLE, DOUBLE}
|
||||
#define ARGS_QQQQ {QUAD, QUAD, QUAD, QUAD}
|
||||
#define ARGS_PPPP {QPACKED, QPACKED, QPACKED, QPACKED}
|
||||
|
||||
#define ALL_SINGLE {SINGLE, SINGLE, SINGLE}
|
||||
#define ALL_DOUBLE {DOUBLE, DOUBLE, DOUBLE}
|
||||
|
||||
|
||||
|
||||
typedef struct e2k_opcode_templ
|
||||
{
|
||||
COMMON_PART;
|
||||
} e2k_opcode_templ;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
COMMON_PART;
|
||||
ALF_PART;
|
||||
} e2k_alf_opcode_templ;
|
||||
|
||||
|
||||
|
||||
#define ALF1_PART \
|
||||
e2k_register_format arg_fmt[3]
|
||||
|
||||
typedef struct
|
||||
{
|
||||
COMMON_PART;
|
||||
ALF_PART;
|
||||
ALF1_PART;
|
||||
} e2k_alf1_opcode_templ;
|
||||
|
||||
|
||||
#define ALF2_PART \
|
||||
e2k_register_format arg_fmt[2]; \
|
||||
u_int8_t opce
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
COMMON_PART;
|
||||
ALF_PART;
|
||||
ALF2_PART;
|
||||
} e2k_alf2_opcode_templ;
|
||||
|
||||
|
||||
|
||||
#define ALF3_PART \
|
||||
e2k_register_format arg_fmt[3]
|
||||
|
||||
typedef struct
|
||||
{
|
||||
COMMON_PART;
|
||||
ALF_PART;
|
||||
ALF3_PART;
|
||||
} e2k_alf3_opcode_templ;
|
||||
|
||||
|
||||
#define ALOPF12_PART \
|
||||
e2k_register_format arg_fmt[2]; \
|
||||
u_int8_t opce; \
|
||||
u_int8_t ales_opce; \
|
||||
u_int8_t ales_opc2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
COMMON_PART;
|
||||
ALF_PART;
|
||||
ALOPF12_PART;
|
||||
} e2k_alopf12_opcode_templ;
|
||||
|
||||
|
||||
|
||||
#define ALOPF13_PART \
|
||||
e2k_register_format arg_fmt[3]; \
|
||||
u_int8_t ales_opce; \
|
||||
u_int8_t ales_opc2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
COMMON_PART;
|
||||
ALF_PART;
|
||||
ALOPF13_PART;
|
||||
} e2k_alopf13_opcode_templ;
|
||||
|
||||
|
||||
|
||||
#define ALOPF15_PART \
|
||||
e2k_register_format arg_fmt
|
||||
|
||||
typedef struct
|
||||
{
|
||||
COMMON_PART;
|
||||
ALF_PART;
|
||||
ALOPF15_PART;
|
||||
} e2k_alopf15_opcode_templ;
|
||||
|
||||
typedef e2k_alopf15_opcode_templ e2k_alopf16_opcode_templ;
|
||||
|
||||
#define CMPsb 0x20
|
||||
#define CMPdb 0x21
|
||||
#define CMPANDsb 0x22
|
||||
#define FXCMPxb 0x2b
|
||||
#define FCMPdb 0x2f
|
||||
|
||||
typedef enum {
|
||||
CMPOPCE_0 = 0,
|
||||
CMPOPCE_1,
|
||||
CMPOPCE_2,
|
||||
CMPOPCE_3,
|
||||
CMPOPCE_4,
|
||||
CMPOPCE_5,
|
||||
CMPOPCE_6,
|
||||
CMPOPCE_7
|
||||
} cmpopce_t;
|
||||
|
||||
#define ALF7_PART \
|
||||
e2k_register_format arg_fmt[2]; \
|
||||
cmpopce_t cmpopce; \
|
||||
int implicit_nops;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
COMMON_PART;
|
||||
ALF_PART;
|
||||
ALF7_PART;
|
||||
} e2k_alf7_opcode_templ;
|
||||
|
||||
#define ALF9_PART \
|
||||
e2k_register_format arg_fmt;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
COMMON_PART;
|
||||
ALF_PART;
|
||||
ALF9_PART;
|
||||
} e2k_alf9_opcode_templ;
|
||||
|
||||
|
||||
#define ALF10_PART \
|
||||
e2k_register_format arg_fmt;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
COMMON_PART;
|
||||
ALF_PART;
|
||||
ALF10_PART;
|
||||
} e2k_alf10_opcode_templ;
|
||||
|
||||
|
||||
#define ALF8_PART \
|
||||
e2k_register_format arg_fmt; \
|
||||
cmpopce_t cmpopce
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
COMMON_PART;
|
||||
ALF_PART;
|
||||
ALF8_PART;
|
||||
} e2k_alf8_opcode_templ;
|
||||
|
||||
#define ALOPF11_PART \
|
||||
e2k_register_format arg_fmt[3]; \
|
||||
u_int8_t ales_opce; \
|
||||
u_int8_t ales_opc2[6]; \
|
||||
int explicit_ales25_v4
|
||||
|
||||
typedef struct
|
||||
{
|
||||
COMMON_PART;
|
||||
ALF_PART;
|
||||
ALOPF11_PART;
|
||||
} e2k_alopf11_opcode_templ;
|
||||
|
||||
|
||||
#define ALOPF11_LIT8_PART \
|
||||
u_int8_t max_lit8; \
|
||||
const char *warn
|
||||
|
||||
typedef struct
|
||||
{
|
||||
COMMON_PART;
|
||||
ALF_PART;
|
||||
ALOPF11_PART;
|
||||
ALOPF11_LIT8_PART;
|
||||
} e2k_alopf11_lit8_opcode_templ;
|
||||
|
||||
|
||||
#define ALOPF21_PART \
|
||||
e2k_register_format arg_fmt[4]; \
|
||||
u_int8_t ales_opc2;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
COMMON_PART;
|
||||
ALF_PART;
|
||||
ALOPF21_PART;
|
||||
} e2k_alopf21_opcode_templ;
|
||||
|
||||
|
||||
#define NO_LABEL 0
|
||||
#define EXPECT_LABEL 1
|
||||
|
||||
#define NO_CTPR {0, 0, 0}
|
||||
#define CTPR2 {0, 1, 0}
|
||||
#define CTPR3 {0, 0, 1}
|
||||
#define ALL_CTPRS {1, 1, 1}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
COMMON_PART;
|
||||
u_int8_t ctp_opc;
|
||||
int allowed_ctprs[3];
|
||||
int label_expected;
|
||||
} e2k_copf2_opcode_templ;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
COMMON_PART;
|
||||
unsigned id;
|
||||
} e2k_setcmd_opcode_templ;
|
||||
|
||||
#define MOVA_PART \
|
||||
u_int16_t opc; \
|
||||
e2k_register_format arg_fmt;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
COMMON_PART;
|
||||
MOVA_PART;
|
||||
} e2k_mova_opcode_templ;
|
||||
|
||||
|
||||
|
||||
|
||||
int parse_alf_args (char **, const e2k_opcode_templ *);
|
||||
int parse_copf2_args (char **, const e2k_opcode_templ *);
|
||||
int parse_pref_args (char **, const e2k_opcode_templ *);
|
||||
int parse_copf4_args (char **, const e2k_opcode_templ *);
|
||||
int parse_nop_args (char **, const e2k_opcode_templ *);
|
||||
int parse_setcmd_args (char **, const e2k_opcode_templ *);
|
||||
int parse_setsft_args (char **, const e2k_opcode_templ *);
|
||||
int parse_wait_args (char **, const e2k_opcode_templ *);
|
||||
int parse_ct_args (char **, const e2k_opcode_templ *);
|
||||
int parse_hcall_args (char **, const e2k_opcode_templ *);
|
||||
int parse_ipd_args (char **, const e2k_opcode_templ *);
|
||||
|
||||
int parse_loop_mode_args (char **, const e2k_opcode_templ *);
|
||||
int parse_alc_args (char **, const e2k_opcode_templ *);
|
||||
int parse_abn_args (char **, const e2k_opcode_templ *);
|
||||
int parse_abp_args (char **, const e2k_opcode_templ *);
|
||||
int parse_abg_args (char **, const e2k_opcode_templ *);
|
||||
int parse_bap_args (char **, const e2k_opcode_templ *);
|
||||
int parse_eap_args (char **, const e2k_opcode_templ *);
|
||||
|
||||
|
||||
int parse_pass_args (char **, const e2k_opcode_templ *);
|
||||
int parse_andp_args (char **, const e2k_opcode_templ *);
|
||||
int parse_landp_args (char **, const e2k_opcode_templ *);
|
||||
int parse_ibranch_args (char **, const e2k_opcode_templ *);
|
||||
int parse_done_hret_glaunch_args (char **, const e2k_opcode_templ *);
|
||||
|
||||
int parse_incr_args (char **, const e2k_opcode_templ *);
|
||||
int parse_mova_args (char **, const e2k_opcode_templ *);
|
||||
int parse_fapb_args (char **, const e2k_opcode_templ *);
|
||||
int parse_movep_args (char **, const e2k_opcode_templ *);
|
||||
|
||||
int parse_flushts_args (char **, const e2k_opcode_templ *);
|
||||
|
||||
int parse_cpl_args (char **, const e2k_opcode_templ *);
|
||||
|
||||
int parse_set_mark_args (char **, const e2k_opcode_templ *);
|
||||
int parse_vfdi_args (char **, const e2k_opcode_templ *);
|
||||
|
||||
|
||||
|
||||
extern struct e2k_opcode_templ *e2k_opcode_templs[];
|
||||
extern size_t e2k_num_opcodes;
|
||||
|
||||
|
||||
typedef enum {
|
||||
WINDOW,
|
||||
BASED,
|
||||
GLOBAL,
|
||||
SPECIAL,
|
||||
AASTI
|
||||
} e2k_register_type;
|
||||
|
||||
typedef struct {
|
||||
u_int8_t idx;
|
||||
e2k_register_type type;
|
||||
e2k_register_format fmt;
|
||||
} e2k_generic_register;
|
||||
|
||||
|
||||
typedef enum {
|
||||
LITERAL_4 = -3,
|
||||
LITERAL_5,
|
||||
/* LITERAL_8 should be used exclusively for encoding ALEF2.opce
|
||||
in PSHUF{W,H}. */
|
||||
LITERAL_8,
|
||||
LITERAL_16,
|
||||
LITERAL_32,
|
||||
LITERAL_64
|
||||
} e2k_literal_size;
|
||||
|
||||
typedef struct {
|
||||
e2k_literal_size size;
|
||||
int sgnd;
|
||||
} e2k_literal_format;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int negated;
|
||||
int pred_num;
|
||||
int pred_fld;
|
||||
} e2k_pred;
|
||||
|
||||
/* The maximal possible number of ALCes in the wide instruction. */
|
||||
#define ALS_CHANNELS_NUMBER 6
|
||||
|
||||
#define opc_field \
|
||||
struct { \
|
||||
u_int8_t cop : 7; \
|
||||
u_int8_t spec : 1; \
|
||||
} opc
|
||||
|
||||
#define GENERIC_ALS \
|
||||
/* May be 1, 2, 3, 5, 6, 7, 8, 9, 10 for appropriate ALF's. */ \
|
||||
int fmt; \
|
||||
/* Pointer to a function which will finalize this ALS after all long \
|
||||
literals in the containing wide instruction have been \
|
||||
accommodated. */ \
|
||||
int (* finish) (struct e2k_als *); \
|
||||
/* The value of ALS which should be encoded. */ \
|
||||
union { \
|
||||
struct { \
|
||||
u_int8_t dst, src2, src1; \
|
||||
opc_field; \
|
||||
} alf1; \
|
||||
struct { \
|
||||
u_int8_t dst, src2, opce; \
|
||||
opc_field; \
|
||||
} alf2; \
|
||||
struct { \
|
||||
u_int8_t src3, src2, src1; \
|
||||
opc_field; \
|
||||
} alf3; \
|
||||
struct { \
|
||||
u_int8_t regn, src2, opce; \
|
||||
opc_field; \
|
||||
} alf5; \
|
||||
struct { \
|
||||
u_int8_t dst, none, regn; \
|
||||
opc_field; \
|
||||
} alf6; \
|
||||
struct { \
|
||||
struct { \
|
||||
u_int8_t pdst : 5; \
|
||||
u_int8_t cmpopce : 3; \
|
||||
} dst2; \
|
||||
u_int8_t src2, src1; \
|
||||
opc_field; \
|
||||
} alf7; \
|
||||
struct { \
|
||||
struct { \
|
||||
u_int8_t pdst : 5; \
|
||||
u_int8_t cmpopce : 3; \
|
||||
} dst2; \
|
||||
u_int8_t src2, opce; \
|
||||
opc_field; \
|
||||
} alf8; \
|
||||
struct { \
|
||||
u_int8_t dst; \
|
||||
u_int8_t opce1_lo; \
|
||||
u_int8_t opce1_hi; \
|
||||
opc_field; \
|
||||
} alf9; \
|
||||
struct { \
|
||||
u_int8_t src3; \
|
||||
u_int8_t opce1_lo; \
|
||||
u_int8_t opce1_hi; \
|
||||
opc_field; \
|
||||
} alf10; \
|
||||
u_int32_t val; \
|
||||
} u[2]; \
|
||||
\
|
||||
/* Therse two are used for quad ops occupying two channels. */ \
|
||||
unsigned real_als_nmb; \
|
||||
/* The first element in real_alses will always be the minor \
|
||||
channel number. I want the user to be able to write \
|
||||
stapq,5 instead of stapq,2. */ \
|
||||
unsigned real_alses[6][2]; \
|
||||
\
|
||||
/* This means that ALS{j,k}.src1 should contain the same value \
|
||||
in both channels. This is required to encode LDAPQ and STAPQ \
|
||||
properly. */ \
|
||||
int same_src1_quad; \
|
||||
\
|
||||
/* The number of valid placements. It can be 6 at maximum, which \
|
||||
corresponds to ALC0, . . , ALC5. */ \
|
||||
int plcmnt_nmb; \
|
||||
int pos[ALS_CHANNELS_NUMBER]; \
|
||||
/* The most optimal index in pos[]. */ \
|
||||
int optimal_plcmnt_idx
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
u_int8_t src3;
|
||||
u_int8_t opc2;
|
||||
} alef1;
|
||||
|
||||
struct {
|
||||
u_int8_t opce;
|
||||
u_int8_t opc2;
|
||||
} alef2;
|
||||
|
||||
u_int16_t hword;
|
||||
} e2k_ales;
|
||||
|
||||
|
||||
extern void init_opcode_templs (void);
|
||||
|
||||
extern int mcpu;
|
|
@ -6,6 +6,7 @@ common_ss.add(when: 'CONFIG_ARM_A64_DIS', if_true: files('arm-a64.cc'))
|
|||
common_ss.add_all(when: 'CONFIG_ARM_A64_DIS', if_true: libvixl_ss)
|
||||
common_ss.add(when: 'CONFIG_CRIS_DIS', if_true: files('cris.c'))
|
||||
common_ss.add(when: 'CONFIG_HEXAGON_DIS', if_true: files('hexagon.c'))
|
||||
common_ss.add(when: 'CONFIG_E2K_DIS', if_true: files('e2k.c'))
|
||||
common_ss.add(when: 'CONFIG_HPPA_DIS', if_true: files('hppa.c'))
|
||||
common_ss.add(when: 'CONFIG_M68K_DIS', if_true: files('m68k.c'))
|
||||
common_ss.add(when: 'CONFIG_MICROBLAZE_DIS', if_true: files('microblaze.c'))
|
||||
|
|
|
@ -241,6 +241,23 @@ enum bfd_architecture
|
|||
#define bfd_mach_cris_v32 32
|
||||
#define bfd_mach_cris_v10_v32 1032
|
||||
bfd_arch_microblaze, /* Xilinx MicroBlaze. */
|
||||
bfd_arch_e2k, /* MCST E2K. */
|
||||
/* It's crucial that the underlying `bfd_mach_e2k*' have the same values as */
|
||||
/* the corresponding `E_E2K_MACH_*'s!!! */
|
||||
#define bfd_mach_e2k_generic 0
|
||||
#define bfd_mach_e2k_ev1 1
|
||||
/* This is interpreted as the common subset of all Elbrus V2 iterations.
|
||||
Currently it is the same as the common subset of all elbrus-2c+. */
|
||||
#define bfd_mach_e2k_ev2 2
|
||||
#define bfd_mach_e2k_ev3 3
|
||||
#define bfd_mach_e2k_ev4 4
|
||||
#define bfd_mach_e2k_ev5 5
|
||||
#define bfd_mach_e2k_ev6 6
|
||||
/* Values 16, 17 and 18 used to be reserved for the first three iterations
|
||||
of `elbrus-v2'. See `include/elf/e2k.h' for why they can't be reused right
|
||||
now. */
|
||||
#define bfd_mach_e2k_8c 19
|
||||
#define bfd_mach_e2k_1cplus 20
|
||||
bfd_arch_moxie, /* The Moxie core. */
|
||||
bfd_arch_ia64, /* HP/Intel ia64 */
|
||||
#define bfd_mach_ia64_elf64 64
|
||||
|
@ -409,6 +426,14 @@ typedef struct disassemble_info {
|
|||
int cap_insn_unit;
|
||||
int cap_insn_split;
|
||||
|
||||
/* If non-zero then try not disassemble beyond this address, even if
|
||||
there are values left in the buffer. This address is the address
|
||||
of the nearest symbol forwards from the start of the disassembly,
|
||||
and it is assumed that it lies on the boundary between instructions.
|
||||
If an instruction spans this address then this is an error in the
|
||||
file being disassembled. */
|
||||
bfd_vma stop_vma;
|
||||
|
||||
} disassemble_info;
|
||||
|
||||
/* Standard disassemblers. Disassemble one instruction at the given
|
||||
|
@ -460,6 +485,7 @@ int print_insn_riscv128 (bfd_vma, disassemble_info*);
|
|||
int print_insn_rx(bfd_vma, disassemble_info *);
|
||||
int print_insn_hexagon(bfd_vma, disassemble_info *);
|
||||
int print_insn_loongarch(bfd_vma, disassemble_info *);
|
||||
int print_insn_e2k (bfd_vma, disassemble_info*);
|
||||
|
||||
#ifdef CONFIG_CAPSTONE
|
||||
bool cap_disas_target(disassemble_info *info, uint64_t pc, size_t size);
|
||||
|
|
|
@ -2334,6 +2334,7 @@ disassemblers = {
|
|||
'avr' : ['CONFIG_AVR_DIS'],
|
||||
'cris' : ['CONFIG_CRIS_DIS'],
|
||||
'hexagon' : ['CONFIG_HEXAGON_DIS'],
|
||||
'e2k' : ['CONFIG_E2K_DIS'],
|
||||
'hppa' : ['CONFIG_HPPA_DIS'],
|
||||
'i386' : ['CONFIG_I386_DIS'],
|
||||
'x86_64' : ['CONFIG_I386_DIS'],
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* E2K cpu parameters for qemu.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef E2K_CPU_PARAM_H
|
||||
#define E2K_CPU_PARAM_H 1
|
||||
|
||||
# define TARGET_LONG_BITS 64
|
||||
# define TARGET_PAGE_BITS 12 /* 4k */
|
||||
# define TARGET_PHYS_ADDR_SPACE_BITS 40
|
||||
# define TARGET_VIRT_ADDR_SPACE_BITS 48
|
||||
# define NB_MMU_MODES 4
|
||||
|
||||
#endif
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Sparc CPU init helpers
|
||||
*
|
||||
* Copyright (c) 2003-2005 Fabrice Bellard
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/log.h"
|
||||
#include "qapi/error.h"
|
||||
#include "cpu.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/qemu-print.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "qapi/visitor.h"
|
||||
#include "hw/core/tcg-cpu-ops.h"
|
||||
|
||||
//#define DEBUG_FEATURES
|
||||
|
||||
static void e2k_cpu_reset(DeviceState *dev)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SOFTMMU
|
||||
static bool e2k_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
static void cpu_e2k_disas_set_info(CPUState *cpu, disassemble_info *info)
|
||||
{
|
||||
info->print_insn = print_insn_e2k;
|
||||
}
|
||||
|
||||
|
||||
void cpu_e2k_set_id(CPUSPARCState *env, unsigned int cpu)
|
||||
{
|
||||
}
|
||||
|
||||
void e2k_cpu_dump_state(CPUState *cs, FILE *f, int flags)
|
||||
{
|
||||
}
|
||||
|
||||
static void e2k_cpu_set_pc(CPUState *cs, vaddr value)
|
||||
{
|
||||
}
|
||||
|
||||
static void e2k_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static bool e2k_cpu_has_work(CPUState *cs)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static char *e2k_cpu_type_name(const char *cpu_model)
|
||||
{
|
||||
char *name = g_strdup_printf("%s", cpu_model);
|
||||
return name;
|
||||
}
|
||||
|
||||
static ObjectClass *e2k_cpu_class_by_name(const char *cpu_model)
|
||||
{
|
||||
ObjectClass *oc;
|
||||
char *typename;
|
||||
|
||||
typename = e2k_cpu_type_name(cpu_model);
|
||||
oc = object_class_by_name(typename);
|
||||
g_free(typename);
|
||||
return oc;
|
||||
}
|
||||
|
||||
static void e2k_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||
{
|
||||
}
|
||||
|
||||
static void e2k_cpu_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
E2KCPUClass *scc = E2K_CPU_CLASS(oc);
|
||||
CPUClass *cc = CPU_CLASS(oc);
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
|
||||
device_class_set_parent_realize(dc, e2k_cpu_realizefn,
|
||||
&scc->parent_realize);
|
||||
|
||||
device_class_set_parent_reset(dc, e2k_cpu_reset, &scc->parent_reset);
|
||||
|
||||
cc->disas_set_info = cpu_e2k_disas_set_info;
|
||||
}
|
||||
|
||||
static const TypeInfo sparc_cpu_type_info = {
|
||||
.name = TYPE_E2K_CPU,
|
||||
.parent = TYPE_CPU,
|
||||
.instance_size = sizeof(E2KCPU),
|
||||
.instance_init = e2k_cpu_initfn,
|
||||
.abstract = true,
|
||||
.class_size = sizeof(E2KCPUClass),
|
||||
.class_init = e2k_cpu_class_init,
|
||||
};
|
||||
|
||||
static void e2k_cpu_cpudef_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
E2KCCPUClass *scc = E2K_CPU_CLASS(oc);
|
||||
scc->cpu_def = data;
|
||||
}
|
||||
|
||||
/*static void e2k_register_cpudef_type(const struct e2k_def_t *def)
|
||||
{
|
||||
char *typename = e2k_cpu_type_name(def->name);
|
||||
TypeInfo ti = {
|
||||
.name = typename,
|
||||
.parent = TYPE_E2K_CPU,
|
||||
.class_init = e2k_cpu_cpudef_class_init,
|
||||
.class_data = (void *)def,
|
||||
};
|
||||
|
||||
type_register(&ti);
|
||||
g_free(typename);
|
||||
}
|
||||
|
||||
static void sparc_cpu_register_types(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
type_register_static(&sparc_cpu_type_info);
|
||||
}
|
||||
|
||||
type_init(sparc_cpu_register_types)
|
|
@ -5,7 +5,7 @@
|
|||
#include "cpu-qom.h"
|
||||
#include "exec/cpu-defs.h"
|
||||
|
||||
struct CPUE2KState {
|
||||
typedef struct CPUArchState {
|
||||
|
||||
/* register file */
|
||||
uint64_t gregs[32]; /* general registers */
|
||||
|
@ -18,13 +18,13 @@ struct CPUE2KState {
|
|||
|
||||
/* special registers */
|
||||
uint64_t *wreg; /* pointer to current window */
|
||||
uint32_t br; /* base register offset, max 128 */
|
||||
uint32_t br; /* base rsegister offset, max 128 */
|
||||
uint64_t ip, nip; /* instruction address, next instruction address */
|
||||
|
||||
uint32_t pfpfr; // Packed Floating Point Flag Register (PFPFR)
|
||||
uint32_t fpcr; // Floating point control register (FPCR)
|
||||
uint32_t fpsr; // Floating point state register (FPSR)
|
||||
};
|
||||
} CPUE2KState;
|
||||
|
||||
/**
|
||||
* E2KCPU:
|
||||
|
@ -32,7 +32,7 @@ struct CPUE2KState {
|
|||
*
|
||||
* An Elbrus CPU.
|
||||
*/
|
||||
struct E2KCPU {
|
||||
struct ArchCPU {
|
||||
/*< private >*/
|
||||
CPUState parent_obj;
|
||||
/*< public >*/
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
e2k_ss = ss.source_set()
|
||||
e2k_ss.add(files())
|
||||
|
||||
# no softmmu support yet
|
||||
|
||||
target_arch += {'e2k': e2k_ss}
|
|
@ -3,6 +3,7 @@ subdir('arm')
|
|||
subdir('avr')
|
||||
subdir('cris')
|
||||
subdir('hexagon')
|
||||
subdir('e2k')
|
||||
subdir('hppa')
|
||||
subdir('i386')
|
||||
subdir('loongarch')
|
||||
|
|
Loading…
Reference in New Issue