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 #ifndef ALPHA_H
00105 #define ALPHA_H
00106
00107 #include <stdio.h>
00108
00109 #include "host.h"
00110 #include "misc.h"
00111 #include "config.h"
00112 #include "endian.h"
00113
00114
00115
00116
00117
00118
00119
00120
00121 #define TARGET_ALPHA
00122
00123
00124 #if defined(BYTES_BIG_ENDIAN)
00125 #define MD_CROSS_ENDIAN
00126 #endif
00127
00128
00129 #define NA 0
00130
00131
00132
00133
00134
00135
00136 #define MD_QWORD_ADDRS
00137
00138
00139 typedef qword_t md_addr_t;
00140
00141
00142
00143
00144
00145
00146
00147 #define MD_PAGE_SIZE 8192
00148 #define MD_LOG_PAGE_SIZE 13
00149
00150
00151
00152
00153
00154
00155 enum md_fault_type {
00156 md_fault_none = 0,
00157 md_fault_access,
00158 md_fault_alignment,
00159 md_fault_overflow,
00160 md_fault_div0,
00161 md_fault_invalid,
00162
00163 md_fault_break,
00164 md_fault_unimpl,
00165 md_fault_internal
00166 };
00167
00168
00169
00170
00171
00172
00173
00174 #define MD_NUM_IREGS 32
00175
00176
00177 #define MD_NUM_FREGS 32
00178
00179
00180 #define MD_NUM_CREGS 2
00181
00182
00183 #define MD_TOTAL_REGS \
00184 (32 + 32 + 2 + 1 + 1 + 1)
00185
00186
00187 typedef qword_t md_gpr_t[MD_NUM_IREGS];
00188
00189
00190 typedef union {
00191 qword_t q[MD_NUM_FREGS];
00192 dfloat_t d[MD_NUM_FREGS];
00193 } md_fpr_t;
00194
00195
00196 typedef struct {
00197 qword_t fpcr;
00198 qword_t uniq;
00199 } md_ctrl_t;
00200
00201
00202 enum md_reg_names {
00203 MD_REG_V0 = 0,
00204 MD_REG_ERR = 7,
00205 MD_REG_FP = 15,
00206 MD_REG_A0 = 16,
00207 MD_REG_A1 = 17,
00208 MD_REG_A2 = 18,
00209 MD_REG_A3 = 19,
00210 MD_REG_A4 = 20,
00211 MD_REG_A5 = 21,
00212 MD_REG_RA = 26,
00213 MD_REG_GP = 29,
00214 MD_REG_SP = 30,
00215 MD_REG_ZERO = 31
00216 };
00217
00218
00219
00220
00221
00222
00223
00224 typedef word_t md_inst_t;
00225
00226
00227 extern md_inst_t MD_NOP_INST;
00228
00229
00230 #ifdef MD_CROSS_ENDIAN
00231
00232 #define MD_SWAPH(X) SWAP_HALF(X)
00233 #define MD_SWAPW(X) SWAP_WORD(X)
00234 #define MD_SWAPQ(X) SWAP_QWORD(X)
00235 #define MD_SWAPI(X) SWAP_WORD(X)
00236
00237 #else
00238
00239 #define MD_SWAPH(X) (X)
00240 #define MD_SWAPW(X) (X)
00241 #define MD_SWAPQ(X) (X)
00242 #define MD_SWAPD(X) (X)
00243 #define MD_SWAPI(X) (X)
00244
00245 #endif
00246
00247
00248 #define MD_FETCH_INST(INST, MEM, PC) \
00249 { (INST) = MEM_READ_WORD((MEM), (PC)); }
00250
00251
00252
00253
00254
00255
00256 #define MD_MAX_ENVIRON 16384
00257
00258
00259
00260
00261
00262
00263
00264 #define MD_TOP_OP(INST) (((INST) >> 26) & 0x3f)
00265 #define MD_SET_OPCODE(OP, INST) \
00266 { OP = md_mask2op[MD_TOP_OP(INST)]; \
00267 while (md_opmask[OP]) \
00268 OP = md_mask2op[((INST >> md_opshift[OP]) & md_opmask[OP]) \
00269 + md_opoffset[OP]]; }
00270
00271
00272
00273 #define MD_MAX_MASK 2048
00274
00275
00276 extern enum md_opcode md_mask2op[];
00277 extern unsigned int md_opoffset[];
00278 extern unsigned int md_opmask[];
00279 extern unsigned int md_opshift[];
00280
00281
00282 enum md_opcode {
00283 OP_NA = 0,
00284 #define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3) OP,
00285 #define DEFLINK(OP,MSK,NAME,MASK,SHIFT) OP,
00286 #define CONNECT(OP)
00287 #include "machine.def"
00288 OP_MAX
00289 };
00290
00291
00292 #define MD_OP_NAME(OP) (md_op2name[OP])
00293 extern char *md_op2name[];
00294
00295
00296 #define MD_OP_FORMAT(OP) (md_op2format[OP])
00297 extern char *md_op2format[];
00298
00299
00300 enum md_fu_class {
00301 FUClamd_NA = 0,
00302 IntALU,
00303 IntMULT,
00304 IntDIV,
00305 FloatADD,
00306 FloatCMP,
00307 FloatCVT,
00308 FloatMULT,
00309 FloatDIV,
00310 FloatSQRT,
00311 RdPort,
00312 WrPort,
00313 NUM_FU_CLASSES
00314 };
00315
00316
00317 #define MD_OP_FUCLASS(OP) (md_op2fu[OP])
00318 extern enum md_fu_class md_op2fu[];
00319
00320
00321 #define MD_FU_NAME(FU) (md_fu2name[FU])
00322 extern char *md_fu2name[];
00323
00324
00325 #define F_ICOMP 0x00000001
00326 #define F_FCOMP 0x00000002
00327 #define F_CTRL 0x00000004
00328 #define F_UNCOND 0x00000008
00329 #define F_COND 0x00000010
00330 #define F_MEM 0x00000020
00331 #define F_LOAD 0x00000040
00332 #define F_STORE 0x00000080
00333 #define F_DISP 0x00000100
00334 #define F_RR 0x00000200
00335 #define F_DIRECT 0x00000400
00336 #define F_TRAP 0x00000800
00337 #define F_LONGLAT 0x00001000
00338 #define F_DIRJMP 0x00002000
00339 #define F_INDIRJMP 0x00004000
00340 #define F_CALL 0x00008000
00341 #define F_FPCOND 0x00010000
00342 #define F_IMM 0x00020000
00343
00344
00345 #define MD_OP_FLAGS(OP) (md_op2flags[OP])
00346 extern unsigned int md_op2flags[];
00347
00348
00349
00350 #define RA ((inst >> 21) & 0x1f)
00351 #define RB ((inst >> 16) & 0x1f)
00352 #define RC (inst & 0x1f)
00353
00354
00355 #define IMM ((qword_t)((inst >> 13) & 0xff))
00356
00357
00358 #define TARG (inst & 0x1fffff)
00359
00360
00361 #define OFS (inst & 0xffff)
00362
00363
00364 #define SEXT(X) \
00365 (((X) & 0x8000) ? ((sqword_t)(X) | LL(0xffffffffffff0000)) : (sqword_t)(X))
00366
00367 #define SEXT21(X) \
00368 (((X) & 0x100000) ? ((sqword_t)(X) | LL(0xffffffffffe00000)) : (sqword_t)(X))
00369
00370 #define SEXT32(X) \
00371 (((X) & 0x80000000) ? ((sqword_t)(X)|LL(0xffffffff00000000)) : (sqword_t)(X))
00372
00373
00374 #define ARITH_OVFL(RESULT, OP1, OP2) ((RESULT) < (OP1) || (RESULT) < (OP2))
00375
00376
00377 #define IEEEFP_DBL_SIGN(Q) ((Q) >> 63)
00378 #define IEEEFP_DBL_EXPONENT(Q) (((Q) >> 52) & 0x7ff)
00379 #define IEEEFP_DBL_FRACTION(Q) ((Q) & ULL(0xfffffffffffff))
00380 #define IS_IEEEFP_DBL_NAN(Q) \
00381 ((IEEEFP_DBL_EXPONENT(Q) == 0x7ff) && (IEEEFP_DBL_FRACTION(Q)))
00382
00383
00384 #ifndef SET_TPC
00385 #define SET_TPC(PC) (void)0
00386 #endif
00387
00388
00389
00390
00391
00392
00393
00394 #define OSF_SYS_exit 1
00395 #define MD_EXIT_SYSCALL(REGS) \
00396 ((REGS)->regs_R[MD_REG_V0] == OSF_SYS_exit)
00397
00398
00399 #define OSF_SYS_write 4
00400 #define MD_OUTPUT_SYSCALL(REGS) \
00401 ((REGS)->regs_R[MD_REG_V0] == OSF_SYS_write \
00402 && ((REGS)->regs_R[MD_REG_A0] == 1 \
00403 || (REGS)->regs_R[MD_REG_A0] == 2))
00404
00405
00406 #define MD_STREAM_FILENO(REGS) ((REGS)->regs_R[MD_REG_A0])
00407
00408
00409 #define MD_IS_CALL(OP) ((OP) == JSR || (OP) == BSR)
00410
00411
00412 #define MD_IS_RETURN(OP) ((OP) == RETN)
00413
00414
00415 #define MD_IS_INDIR(OP) \
00416 ((OP) == JMP || (OP) == JSR || (OP) == RETN || (OP) == JSR_COROUTINE)
00417
00418
00419 enum md_amode_type {
00420 md_amode_imm,
00421 md_amode_gp,
00422 md_amode_sp,
00423 md_amode_fp,
00424 md_amode_disp,
00425 md_amode_rr,
00426 md_amode_NUM
00427 };
00428 extern char *md_amode_str[md_amode_NUM];
00429
00430
00431 #define MD_AMODE_PREPROBE(OP, FSM) { (FSM) = 0; }
00432
00433
00434 #define MD_AMODE_PROBE(AM, OP, FSM) \
00435 { \
00436 if (MD_OP_FLAGS(OP) & F_DISP) \
00437 { \
00438 if ((RB) == MD_REG_GP) \
00439 (AM) = md_amode_gp; \
00440 else if ((RB) == MD_REG_SP) \
00441 (AM) = md_amode_sp; \
00442 else if ((RB) == MD_REG_FP) \
00443 (AM) = md_amode_fp; \
00444 else \
00445 (AM) = md_amode_disp; \
00446 } \
00447 else if (MD_OP_FLAGS(OP) & F_RR) \
00448 (AM) = md_amode_rr; \
00449 else \
00450 panic("cannot decode addressing mode"); \
00451 }
00452
00453
00454 #define MD_AMODE_POSTPROBE(FSM)
00455
00456
00457
00458
00459
00460
00461
00462 #define MD_EIO_FILE_FORMAT EIO_ALPHA_FORMAT
00463
00464 #define MD_MISC_REGS_TO_EXO(REGS) \
00465 exo_new(ec_list, \
00466 exo_new(ec_integer, (exo_integer_t)sim_num_insn), \
00467 exo_new(ec_address, (exo_integer_t)(REGS)->regs_PC), \
00468 exo_new(ec_address, (exo_integer_t)(REGS)->regs_NPC), \
00469 exo_new(ec_integer, (exo_integer_t)(REGS)->regs_C.fpcr),\
00470 exo_new(ec_integer, (exo_integer_t)(REGS)->regs_C.uniq),\
00471 NULL)
00472
00473 #define MD_IREG_TO_EXO(REGS, IDX) \
00474 exo_new(ec_address, (exo_integer_t)(REGS)->regs_R[IDX])
00475
00476 #define MD_FREG_TO_EXO(REGS, IDX) \
00477 exo_new(ec_address, (exo_integer_t)(REGS)->regs_F.q[IDX])
00478
00479 #define MD_EXO_TO_MISC_REGS(EXO, ICNT, REGS) \
00480 \
00481 if (!exo \
00482 || exo->ec != ec_list \
00483 || !exo->as_list.head \
00484 || exo->as_list.head->ec != ec_integer \
00485 || !exo->as_list.head->next \
00486 || exo->as_list.head->next->ec != ec_address \
00487 || !exo->as_list.head->next->next \
00488 || exo->as_list.head->next->next->ec != ec_address \
00489 || !exo->as_list.head->next->next->next \
00490 || exo->as_list.head->next->next->next->ec != ec_integer \
00491 || !exo->as_list.head->next->next->next->next \
00492 || exo->as_list.head->next->next->next->next->ec != ec_integer \
00493 || exo->as_list.head->next->next->next->next->next != NULL) \
00494 fatal("could not read EIO misc regs"); \
00495 (ICNT) = (counter_t)exo->as_list.head->as_integer.val; \
00496 (REGS)->regs_PC = (md_addr_t)exo->as_list.head->next->as_integer.val; \
00497 (REGS)->regs_NPC = \
00498 (md_addr_t)exo->as_list.head->next->next->as_integer.val; \
00499 (REGS)->regs_C.fpcr = \
00500 (qword_t)exo->as_list.head->next->next->next->as_integer.val; \
00501 (REGS)->regs_C.uniq = \
00502 (qword_t)exo->as_list.head->next->next->next->next->as_integer.val;
00503
00504 #define MD_EXO_TO_IREG(EXO, REGS, IDX) \
00505 ((REGS)->regs_R[IDX] = (qword_t)(EXO)->as_integer.val)
00506
00507 #define MD_EXO_TO_FREG(EXO, REGS, IDX) \
00508 ((REGS)->regs_F.q[IDX] = (qword_t)(EXO)->as_integer.val)
00509
00510 #define MD_EXO_CMP_IREG(EXO, REGS, IDX) \
00511 ((REGS)->regs_R[IDX] != (qword_t)(EXO)->as_integer.val)
00512
00513 #define MD_FIRST_IN_REG 0
00514 #define MD_LAST_IN_REG 21
00515
00516 #define MD_FIRST_OUT_REG 0
00517 #define MD_LAST_OUT_REG 21
00518
00519
00520
00521
00522
00523
00524
00525 typedef qword_t exo_address_t;
00526
00527
00528 typedef qword_t exo_integer_t;
00529
00530
00531 typedef double exo_float_t;
00532
00533
00534
00535
00536
00537
00538
00539 #define stat_reg_counter stat_reg_sqword
00540 #define sc_counter sc_sqword
00541 #define for_counter for_sqword
00542
00543
00544 #define stat_reg_addr stat_reg_qword
00545
00546
00547
00548
00549
00550
00551
00552 enum md_reg_type {
00553 rt_gpr,
00554 rt_lpr,
00555 rt_fpr,
00556 rt_dpr,
00557 rt_ctrl,
00558 rt_PC,
00559 rt_NPC,
00560 rt_NUM
00561 };
00562
00563
00564 struct md_reg_names_t {
00565 char *str;
00566 enum md_reg_type file;
00567 int reg;
00568 };
00569
00570
00571 extern struct md_reg_names_t md_reg_names[];
00572
00573
00574 char *md_reg_name(enum md_reg_type rt, int reg);
00575
00576
00577 struct eval_value_t;
00578 struct regs_t;
00579 char *
00580 md_reg_obj(struct regs_t *regs,
00581 int is_write,
00582 enum md_reg_type rt,
00583 int reg,
00584 struct eval_value_t *val);
00585
00586
00587 void md_print_ireg(md_gpr_t regs, int reg, FILE *stream);
00588 void md_print_iregs(md_gpr_t regs, FILE *stream);
00589
00590
00591 void md_print_fpreg(md_fpr_t regs, int reg, FILE *stream);
00592 void md_print_fpregs(md_fpr_t regs, FILE *stream);
00593
00594
00595 void md_print_creg(md_ctrl_t regs, int reg, FILE *stream);
00596 void md_print_cregs(md_ctrl_t regs, FILE *stream);
00597
00598
00599 word_t md_xor_regs(struct regs_t *regs);
00600
00601
00602
00603
00604
00605
00606
00607 #define MD_AGEN_OP ADDQ
00608
00609
00610 #define MD_NOP_OP OP_NA
00611
00612
00613
00614 #define MD_VALID_ADDR(ADDR) \
00615 (((ADDR) >= ld_text_base && (ADDR) < (ld_text_base + ld_text_size)) \
00616 || ((ADDR) >= ld_data_base && (ADDR) < ld_brk_point) \
00617 || ((ADDR) >= (ld_stack_base - 16*1024*1024) && (ADDR) < ld_stack_base))
00618
00619
00620
00621
00622
00623
00624
00625 #define MD_BR_SHIFT 2
00626
00627
00628
00629
00630
00631
00632
00633 void md_init_decoder(void);
00634
00635
00636 void
00637 md_print_insn(md_inst_t inst,
00638 md_addr_t pc,
00639 FILE *stream);
00640
00641 #endif
00642
00643
00644
00645
00646
00647
00648
00649 #if 0
00650
00651
00652 typedef qword_t MD_ADDR_TYPE;
00653 typedef qword_t MD_PTR_TYPE;
00654 typedef word_t MD_INST_TYPE;
00655 #define MD_INST_SIZE sizeof(MD_INST_TYPE)
00656
00657
00658 #define MD_TEXT_BASE 0x20000000ULL
00659 #define MD_STACK_BASE (MD_TEXT_BASE - (409600+4096))
00660
00661
00662 enum { REG_V0, REG_A0=16, REG_A1, REG_A2, REG_A3, REG_A4, REG_A5, REG_ERR=7,
00663 REG_GP=29, REG_SP, REG_ZERO, REG_RA=26 };
00664
00665
00666 #define MD_TOTAL_REGS \
00667 (MD_NUM_REGS+MD_NUM_REGS+1+1+1+1)
00668
00669
00670 #ifndef NO_ICHECKS
00671
00672
00673
00674
00675
00676 #ifndef IFAIL
00677 #define IFAIL(S) fatal(S)
00678 #endif
00679
00680
00681 #define OVER(X,Y) (((((X) > 0) && ((Y) > 0) \
00682 && (MAXINT_VAL - (X) < (Y))) \
00683 ? IFAIL("+ overflow") : (void)0), \
00684 ((((X) < 0) && ((Y) < 0) \
00685 && (-MAXINT_VAL - (X) > (Y))) \
00686 ? IFAIL("+ underflow") : (void)0))
00687
00688
00689 #define UNDER(X,Y) (((((X) > 0) && ((Y) < 0) \
00690 && (MAXINT_VAL + (Y) < (X))) \
00691 ? IFAIL("- overflow") : (void)0), \
00692 ((((X) < 0) && ((Y) > 0) \
00693 && (-MAXINT_VAL + (Y) > (X))) \
00694 ? IFAIL("- underflow") : (void)0))
00695
00696
00697 #define DIV0(N) (((N) == 0) ? IFAIL("divide by 0") : (void)0)
00698
00699
00700 #define INTALIGN(N) (((N) & 01) \
00701 ? IFAIL("bad INT register alignment") : (void)0)
00702
00703
00704 #define FPALIGN(N) (((N) & 01) \
00705 ? IFAIL("bad FP register alignment") : (void)0)
00706
00707
00708 #define TALIGN(TARG) (((TARG) & 0x7) \
00709 ? IFAIL("bad jump alignment") : (void)0)
00710
00711 #else
00712
00713
00714 #define OVER(X,Y) ((void)0)
00715 #define UNDER(X,Y) ((void)0)
00716 #define DIV0(N) ((void)0)
00717 #define INTALIGN(N) ((void)0)
00718 #define FPALIGN(N) ((void)0)
00719 #define TALIGN(TARG) ((void)0)
00720
00721 #endif
00722
00723
00724
00725
00726 #define IDIV(A, B) ((A) / (B))
00727 #define IMOD(A, B) ((A) % (B))
00728 #define FDIV(A, B) ((A) / (B))
00729 #define FINT(A) ((int)A)
00730
00731 #endif