00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 #ifndef ARM_H
00169 #define ARM_H
00170
00171 #include <stdio.h>
00172
00173 #include "host.h"
00174 #include "misc.h"
00175 #include "config.h"
00176 #include "endian.h"
00177
00178
00179
00180
00181
00182
00183
00184
00185 #define TARGET_ARM
00186
00187
00188 #if defined(BYTES_BIG_ENDIAN)
00189 #define MD_CROSS_ENDIAN
00190 #endif
00191
00192
00193 #define NA 0
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 typedef word_t md_addr_t;
00204
00205
00206
00207
00208
00209
00210
00211 #define MD_PAGE_SIZE 4096
00212 #define MD_LOG_PAGE_SIZE 12
00213
00214
00215
00216
00217
00218
00219 enum md_fault_type {
00220 md_fault_none = 0,
00221 md_fault_access,
00222 md_fault_alignment,
00223 md_fault_overflow,
00224 md_fault_div0,
00225 md_fault_invalid,
00226
00227 md_fault_break,
00228 md_fault_unimpl,
00229 md_fault_internal
00230 };
00231
00232
00233
00234
00235
00236
00237
00238 #define MD_NUM_IREGS (16 + 16)
00239
00240
00241 #define MD_NUM_FREGS 8
00242
00243
00244 #define MD_NUM_CREGS 3
00245
00246
00247 #define MD_TOTAL_REGS \
00248 (32 + 8 + 3 + 1 + 1 + 1)
00249
00250
00251 typedef word_t md_gpr_t[MD_NUM_IREGS];
00252
00253
00254 typedef union {
00255 qword_t q[MD_NUM_FREGS];
00256 dfloat_t d[MD_NUM_FREGS];
00257 } md_fpr_t;
00258
00259
00260 typedef struct {
00261 word_t cpsr;
00262 word_t spsr;
00263 word_t fpsr;
00264 } md_ctrl_t;
00265
00266
00267 enum md_reg_names {
00268 MD_REG_R0 = 0,
00269 MD_REG_V0 = 0,
00270 MD_REG_A0 = 0,
00271 MD_REG_R1 = 1,
00272 MD_REG_A1 = 1,
00273 MD_REG_R2 = 2,
00274 MD_REG_A2 = 2,
00275 MD_REG_R3 = 3,
00276 MD_REG_A3 = 3,
00277 MD_REG_R4 = 4,
00278 MD_REG_R5 = 5,
00279 MD_REG_R6 = 6,
00280 MD_REG_R7 = 7,
00281 MD_REG_R8 = 8,
00282 MD_REG_R9 = 9,
00283 MD_REG_R10 = 10,
00284 MD_REG_SL = 10,
00285 MD_REG_R11 = 11,
00286 MD_REG_FP = 11,
00287 MD_REG_R12 = 12,
00288 MD_REG_IP = 12,
00289 MD_REG_R13 = 13,
00290 MD_REG_SP = 13,
00291 MD_REG_R14 = 14,
00292 MD_REG_LR = 14,
00293 MD_REG_R15 = 15,
00294 MD_REG_PC = 15,
00295 MD_REG_TMP0 = 16,
00296 MD_REG_TMP1 = 17,
00297 MD_REG_TMP2 = 18,
00298 MD_REG_TMP3 = 19
00299 };
00300
00301
00302
00303
00304
00305
00306 typedef word_t md_inst_t;
00307
00308
00309 extern md_inst_t MD_NOP_INST;
00310
00311
00312 #ifdef MD_CROSS_ENDIAN
00313
00314 #define MD_SWAPH(X) SWAP_HALF(X)
00315 #define MD_SWAPW(X) SWAP_WORD(X)
00316 #define MD_SWAPQ(X) SWAP_QWORD(X)
00317 #define MD_SWAPI(X) SWAP_WORD(X)
00318
00319 #else
00320
00321 #define MD_SWAPH(X) (X)
00322 #define MD_SWAPW(X) (X)
00323 #define MD_SWAPQ(X) (X)
00324 #define MD_SWAPD(X) (X)
00325 #define MD_SWAPI(X) (X)
00326
00327 #endif
00328
00329
00330 #define MD_FETCH_INST(INST, MEM, PC) \
00331 { (INST) = MEM_READ_WORD((MEM), (PC)); }
00332
00333
00334
00335
00336
00337
00338 #define MD_MAX_ENVIRON 16384
00339
00340
00341
00342
00343
00344
00345
00346 #define MD_TOP_OP(INST) (((INST) >> 24) & 0x0f)
00347 #define MD_SET_OPCODE(OP, INST) \
00348 { OP = md_mask2op[MD_TOP_OP(INST)]; \
00349 while (md_opmask[OP]) \
00350 OP = md_mask2op[((INST >> md_opshift[OP]) & md_opmask[OP]) \
00351 + md_opoffset[OP]]; }
00352
00353
00354
00355 #define MD_MAX_MASK 2048
00356
00357
00358 enum md_opcode {
00359 OP_NA = 0,
00360 #define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,O3,I1,I2,I3,I4) OP,
00361 #define DEFUOP(OP,NAME,OPFORM,RES,FLAGS,O1,O2,O3,I1,I2,I3,I4) OP,
00362 #define DEFLINK(OP,MSK,NAME,MASK,SHIFT) OP,
00363 #define CONNECT(OP)
00364 #include "machine.def"
00365 OP_MAX
00366 };
00367
00368
00369
00370 extern enum md_opcode md_mask2op[];
00371 extern unsigned int md_opoffset[];
00372 extern unsigned int md_opmask[];
00373 extern unsigned int md_opshift[];
00374
00375
00376
00377 #define MD_OP_NAME(OP) (md_op2name[OP])
00378 extern char *md_op2name[];
00379
00380
00381 #define MD_OP_FORMAT(OP) (md_op2format[OP])
00382 extern char *md_op2format[];
00383
00384
00385 enum md_fu_class {
00386 FUClamd_NA = 0,
00387 IntALU,
00388 IntMULT,
00389 IntDIV,
00390 FloatADD,
00391 FloatCMP,
00392 FloatCVT,
00393 FloatMULT,
00394 FloatDIV,
00395 FloatSQRT,
00396 RdPort,
00397 WrPort,
00398 NUM_FU_CLASSES
00399 };
00400
00401
00402 #define MD_OP_FUCLASS(OP) (md_op2fu[OP])
00403 extern enum md_fu_class md_op2fu[];
00404
00405
00406 #define MD_FU_NAME(FU) (md_fu2name[FU])
00407 extern char *md_fu2name[];
00408
00409
00410 #define F_ICOMP 0x00000001
00411 #define F_FCOMP 0x00000002
00412 #define F_CTRL 0x00000004
00413 #define F_UNCOND 0x00000008
00414 #define F_COND 0x00000010
00415 #define F_MEM 0x00000020
00416 #define F_LOAD 0x00000040
00417 #define F_STORE 0x00000080
00418 #define F_DISP 0x00000100
00419 #define F_RR 0x00000200
00420 #define F_DIRECT 0x00000400
00421 #define F_TRAP 0x00000800
00422 #define F_LONGLAT 0x00001000
00423 #define F_DIRJMP 0x00002000
00424 #define F_INDIRJMP 0x00004000
00425 #define F_CALL 0x00008000
00426 #define F_FPCOND 0x00010000
00427 #define F_IMM 0x00020000
00428 #define F_CISC 0x00040000
00429 #define F_AGEN 0x00080000
00430
00431
00432 #define MD_OP_FLAGS(OP) (md_op2flags[OP])
00433 extern unsigned int md_op2flags[];
00434
00435
00436
00437 #define RN ((inst >> 16) & 0x0f)
00438 #define URN ((inst >> 17) & 0x1f)
00439 #define RD ((inst >> 12) & 0x0f)
00440 #define URD ((inst >> 12) & 0x1f)
00441 #define RS ((inst >> 8) & 0x0f)
00442 #define RM (inst & 0x0f)
00443
00444
00445 #define FN ((inst >> 16) & 0x07)
00446 #define FD ((inst >> 12) & 0x07)
00447 #define FM (inst & 0x07)
00448
00449
00450 #define SHIFT_BITS ((inst >> 4) & 0xff)
00451 #define SHIFT_REG ((inst >> 4) & 0x01)
00452 #define SHIFT_REG_PAD ((inst >> 7) & 0x01)
00453 #define SHIFT_TYPE ((inst >> 5) & 0x03)
00454 #define SHIFT_SHAMT ((inst >> 7) & 0x1f)
00455
00456
00457 #define SHIFT_LSL 0x00
00458 #define SHIFT_LSR 0x01
00459 #define SHIFT_ASR 0x02
00460 #define SHIFT_ROR 0x03
00461
00462
00463 #define ROTIMM (inst & 0xff)
00464 #define ROTAMT ((inst >> 8) & 0x0f)
00465
00466
00467 #define ROTR(VAL,N) \
00468 (((VAL) >> (int)((N) & 31)) | ((VAL) << (32 - (int)((N) & 31))))
00469
00470
00471 #define OFS ((word_t)(inst & 0xfff))
00472
00473
00474 #define HOFS ((word_t)((RS << 4) + RM))
00475
00476
00477 #define FPOFS ((word_t)((inst & 0xff) << 2))
00478
00479
00480 #define BOFS \
00481 ((inst & 0x800000) \
00482 ? (0xfc000000 | ((inst & 0xffffff) << 2)) \
00483 : ((inst & 0x7fffff) << 2))
00484
00485 #if 0
00486 #define BOFS ((((word_t)(inst & 0xffffff)) >> 23) ? ((word_t)(-67108864 + (word_t)(((inst & 0xffffff) << 2)))) : ((word_t)((inst & 0xffffff)) << 2))
00487 #endif
00488
00489
00490 #define CPOPC ((inst >> 20) & 0x0f)
00491 #define CPEXT ((inst >> 5) & 0x07)
00492
00493
00494 #define SEXT24(X) \
00495 (((X) & 0x800000) ? ((sword_t)(X) | 0xff800000)) : (sqword_t)(X))
00496
00497
00498 #define LDST_PU ((inst >> 23) & 0x03)
00499 #define REGLIST (inst & 0xffff)
00500
00501
00502 #define FPIMMBITS (inst & 0x07)
00503 #define FPIMM (md_fpimm[FPIMMBITS])
00504 extern double md_fpimm[8];
00505
00506 #define EF_SIZE (((inst >> 18) & 0x02) | ((inst >> 7) & 0x01))
00507 #define LDST_EF_SIZE (((inst >> 21) & 0x02) | ((inst >> 15) & 0x01))
00508 #define GH_RNDMODE ((inst >> 5) & 0x03)
00509 #define FCNT (((inst >> 21) & 0x02) | ((inst >> 15) & 0x01))
00510
00511
00512 #define ONES(EXPR) (md_ones(EXPR))
00513
00514
00515 int md_ones(word_t val);
00516
00517
00518 #define ADDC(LHS, RHS, RES) md_addc((LHS), (RHS), (RES))
00519 #define ADDV(LHS, RHS, RES) md_addv((LHS), (RHS), (RES))
00520 #define SUBC(LHS, RHS, RES) md_subc((LHS), (RHS), (RES))
00521 #define SUBV(LHS, RHS, RES) md_subv((LHS), (RHS), (RES))
00522
00523 int md_addc(word_t lhs, word_t rhs, word_t res);
00524 int md_addv(word_t lhs, word_t rhs, word_t res);
00525 int md_subc(word_t lhs, word_t rhs, word_t res);
00526 int md_subv(word_t lhs, word_t rhs, word_t res);
00527
00528
00529 #define SYSCODE (inst & 0xffffff)
00530
00531
00532 #ifndef SET_TPC
00533 #define SET_TPC(PC) (void)0
00534 #endif
00535
00536
00537 #define _PSR_N(PSR) (((PSR) >> 31) & 1)
00538 #define _SET_PSR_N(PSR, VAL) \
00539 ((PSR) = (((PSR) & ~(1 << 31)) | (((VAL) & 1) << 31)))
00540 #define _PSR_Z(PSR) (((PSR) >> 30) & 1)
00541 #define _SET_PSR_Z(PSR, VAL) \
00542 ((PSR) = (((PSR) & ~(1 << 30)) | (((VAL) & 1) << 30)))
00543 #define _PSR_C(PSR) (((PSR) >> 29) & 1)
00544 #define _SET_PSR_C(PSR, VAL) \
00545 ((PSR) = (((PSR) & ~(1 << 29)) | (((VAL) & 1) << 29)))
00546 #define _PSR_V(PSR) (((PSR) >> 28) & 1)
00547 #define _SET_PSR_V(PSR, VAL) \
00548 ((PSR) = (((PSR) & ~(1 << 28)) | (((VAL) & 1) << 28)))
00549
00550 #define _PSR_IRQ(PSR) (((PSR) >> 7) & 1)
00551 #define _PSR_FIQ(PSR) (((PSR) >> 6) & 1)
00552 #define _PSR_MODE(PSR) ((PSR) & 0x1f)
00553
00554
00555 #define COND_EQ 0x00
00556 #define COND_NE 0x01
00557 #define COND_CS 0x02
00558 #define COND_CC 0x03
00559 #define COND_MI 0x04
00560 #define COND_PL 0x05
00561 #define COND_VS 0x06
00562 #define COND_VC 0x07
00563 #define COND_HI 0x08
00564 #define COND_LS 0x09
00565 #define COND_GE 0x0a
00566 #define COND_LT 0x0b
00567 #define COND_GT 0x0c
00568 #define COND_LE 0x0d
00569 #define COND_AL 0x0e
00570 #define COND_NV 0x0f
00571
00572
00573 #define COND ((inst >> 28) & 0x0f)
00574
00575
00576 #define COND_VALID(PSR) (((COND) == COND_AL) || md_cond_ok(inst, PSR))
00577
00578
00579 extern int md_cond_ok(md_inst_t inst, word_t psr);
00580
00581
00582 #define SHIFTRM(RMVAL, RSVAL, CFVAL) \
00583 (((SHIFT_BITS)==0) ? (RMVAL) : md_shiftrm(inst, (RMVAL), (RSVAL), (CFVAL)))
00584
00585
00586 extern word_t
00587 md_shiftrm(md_inst_t inst, word_t rmval, word_t rs_val, word_t psr);
00588
00589 #define SHIFTC(RMVAL, RSVAL, CFVAL) \
00590 (((SHIFT_BITS)==0) ? (CFVAL) : md_shiftc(inst, (RMVAL), (RSVAL), (CFVAL)))
00591
00592
00593 word_t
00594 md_shiftc(md_inst_t inst, word_t rmval, word_t rsval, word_t cfval);
00595
00596
00597
00598
00599
00600
00601 #define OSF_SYS_exit 1
00602 #define MD_EXIT_SYSCALL(REGS) \
00603 ((REGS)->regs_R[MD_REG_V0] == OSF_SYS_exit)
00604
00605
00606 #define OSF_SYS_write 4
00607 #define MD_OUTPUT_SYSCALL(REGS) \
00608 ((REGS)->regs_R[MD_REG_V0] == OSF_SYS_write \
00609 && ((REGS)->regs_R[MD_REG_A0] == 1 \
00610 || (REGS)->regs_R[MD_REG_A0] == 2))
00611
00612
00613 #define MD_STREAM_FILENO(REGS) ((REGS)->regs_R[MD_REG_A0])
00614
00615
00616 #define MD_IS_CALL(OP) ((OP) == BRL)
00617
00618
00619
00620 #define MD_IS_RETURN(OP) ((OP) == MOV)
00621
00622
00623
00624 #define MD_IS_INDIR(OP) ((OP) == MOV)
00625
00626
00627 enum md_amode_type {
00628 md_amode_imm,
00629 md_amode_gp,
00630 md_amode_sp,
00631 md_amode_fp,
00632 md_amode_disp,
00633 md_amode_rr,
00634 md_amode_NUM
00635 };
00636 extern char *md_amode_str[md_amode_NUM];
00637
00638
00639 #define MD_AMODE_PREPROBE(OP, FSM) { (FSM) = 0; }
00640
00641
00642 #define MD_AMODE_PROBE(AM, OP, FSM) \
00643 { \
00644 if (MD_OP_FLAGS(OP) & F_DISP) \
00645 { \
00646 if ((RB) == MD_REG_GP) \
00647 (AM) = md_amode_gp; \
00648 else if ((RB) == MD_REG_SP) \
00649 (AM) = md_amode_sp; \
00650 else if ((RB) == MD_REG_FP) \
00651 (AM) = md_amode_fp; \
00652 else \
00653 (AM) = md_amode_disp; \
00654 } \
00655 else if (MD_OP_FLAGS(OP) & F_RR) \
00656 (AM) = md_amode_rr; \
00657 else \
00658 panic("cannot decode addressing mode"); \
00659 }
00660
00661
00662 #define MD_AMODE_POSTPROBE(FSM)
00663
00664
00665
00666
00667
00668
00669
00670 #define MD_EIO_FILE_FORMAT EIO_ALPHA_FORMAT
00671
00672 #define MD_MISC_REGS_TO_EXO(REGS) \
00673 exo_new(ec_list, \
00674 exo_new(ec_integer, (exo_integer_t)sim_num_insn), \
00675 exo_new(ec_address, (exo_integer_t)(REGS)->regs_PC), \
00676 exo_new(ec_address, (exo_integer_t)(REGS)->regs_NPC), \
00677 NULL)
00678
00679 #if XXX
00680 exo_new(ec_integer, (exo_integer_t)(REGS)->regs_C.fpcr),
00681 exo_new(ec_integer, (exo_integer_t)(REGS)->regs_C.uniq),
00682 #endif
00683
00684 #define MD_IREG_TO_EXO(REGS, IDX) \
00685 exo_new(ec_address, (exo_integer_t)(REGS)->regs_R[IDX])
00686
00687 #define MD_FREG_TO_EXO(REGS, IDX) \
00688 exo_new(ec_address, (exo_integer_t)(REGS)->regs_F.q[IDX])
00689
00690 #define MD_EXO_TO_MISC_REGS(EXO, ICNT, REGS) \
00691 \
00692 if (!exo \
00693 || exo->ec != ec_list \
00694 || !exo->as_list.head \
00695 || exo->as_list.head->ec != ec_integer \
00696 || !exo->as_list.head->next \
00697 || exo->as_list.head->next->ec != ec_address \
00698 || !exo->as_list.head->next->next \
00699 || exo->as_list.head->next->next->ec != ec_address \
00700 || !exo->as_list.head->next->next->next \
00701 || exo->as_list.head->next->next->next->ec != ec_integer \
00702 || !exo->as_list.head->next->next->next->next \
00703 || exo->as_list.head->next->next->next->next->ec != ec_integer \
00704 || exo->as_list.head->next->next->next->next->next != NULL) \
00705 fatal("could not read EIO misc regs"); \
00706 (ICNT) = (counter_t)exo->as_list.head->as_integer.val; \
00707 (REGS)->regs_PC = (md_addr_t)exo->as_list.head->next->as_integer.val; \
00708 (REGS)->regs_NPC = \
00709 (md_addr_t)exo->as_list.head->next->next->as_integer.val;
00710
00711 #if XXX
00712 (REGS)->regs_C.fpcr =
00713 (qword_t)exo->as_list.head->next->next->next->as_integer.val;
00714 (REGS)->regs_C.uniq =
00715 (qword_t)exo->as_list.head->next->next->next->next->as_integer.val;
00716 #endif
00717
00718 #define MD_EXO_TO_IREG(EXO, REGS, IDX) \
00719 ((REGS)->regs_R[IDX] = (qword_t)(EXO)->as_integer.val)
00720
00721 #define MD_EXO_TO_FREG(EXO, REGS, IDX) \
00722 ((REGS)->regs_F.q[IDX] = (qword_t)(EXO)->as_integer.val)
00723
00724 #define MD_EXO_CMP_IREG(EXO, REGS, IDX) \
00725 ((REGS)->regs_R[IDX] != (qword_t)(EXO)->as_integer.val)
00726
00727 #define MD_FIRST_IN_REG 0
00728 #define MD_LAST_IN_REG 21
00729
00730 #define MD_FIRST_OUT_REG 0
00731 #define MD_LAST_OUT_REG 21
00732
00733
00734
00735
00736
00737
00738
00739 typedef qword_t exo_address_t;
00740
00741
00742 typedef qword_t exo_integer_t;
00743
00744
00745 typedef double exo_float_t;
00746
00747
00748
00749
00750
00751
00752
00753 #define stat_reg_counter stat_reg_sqword
00754 #define sc_counter sc_sqword
00755 #define for_counter for_sqword
00756
00757
00758 #define stat_reg_addr stat_reg_uint
00759
00760
00761
00762
00763
00764
00765
00766 enum md_reg_type {
00767 rt_gpr,
00768 rt_lpr,
00769 rt_fpr,
00770 rt_dpr,
00771 rt_ctrl,
00772 rt_PC,
00773 rt_NPC,
00774 rt_NUM
00775 };
00776
00777
00778 struct md_reg_names_t {
00779 char *str;
00780 enum md_reg_type file;
00781 int reg;
00782 };
00783
00784
00785 extern struct md_reg_names_t md_reg_names[];
00786
00787
00788 char *md_reg_name(enum md_reg_type rt, int reg);
00789
00790
00791 struct eval_value_t;
00792 struct regs_t;
00793 char *
00794 md_reg_obj(struct regs_t *regs,
00795 int is_write,
00796 enum md_reg_type rt,
00797 int reg,
00798 struct eval_value_t *val);
00799
00800
00801 void md_print_ireg(md_gpr_t regs, int reg, FILE *stream);
00802 void md_print_iregs(md_gpr_t regs, FILE *stream);
00803
00804
00805 void md_print_fpreg(md_fpr_t regs, int reg, FILE *stream);
00806 void md_print_fpregs(md_fpr_t regs, FILE *stream);
00807
00808
00809 void md_print_creg(md_ctrl_t regs, int reg, FILE *stream);
00810 void md_print_cregs(md_ctrl_t regs, FILE *stream);
00811
00812
00813 word_t md_xor_regs(struct regs_t *regs);
00814
00815
00816
00817
00818
00819
00820
00821 #define MD_AGEN_OP ADDQ
00822
00823
00824 #define MD_NOP_OP OP_NA
00825
00826
00827
00828 #define MD_VALID_ADDR(ADDR) \
00829 (((ADDR) >= ld_text_base && (ADDR) < (ld_text_base + ld_text_size)) \
00830 || ((ADDR) >= ld_data_base && (ADDR) < ld_brk_point) \
00831 || ((ADDR) >= (ld_stack_base - 16*1024*1024) && (ADDR) < ld_stack_base))
00832
00833
00834
00835
00836
00837
00838
00839 #define MD_BR_SHIFT 2
00840
00841
00842
00843
00844
00845
00846
00847 void md_init_decoder(void);
00848
00849
00850 #define MD_MAX_FLOWLEN 64
00851 struct md_uop_t {
00852 enum md_opcode op;
00853 md_inst_t inst;
00854 };
00855
00856
00857
00858 int
00859 md_get_flow(enum md_opcode op, md_inst_t inst,
00860 struct md_uop_t flow[MD_MAX_FLOWLEN]);
00861
00862
00863 void
00864 md_print_insn(md_inst_t inst,
00865 md_addr_t pc,
00866 FILE *stream);
00867
00868
00869 void
00870 md_print_uop(enum md_opcode op,
00871 md_inst_t inst,
00872 md_addr_t pc,
00873 FILE *stream);
00874
00875 #endif