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 #ifndef PISA_H
00094 #define PISA_H
00095
00096 #include <stdio.h>
00097
00098 #include "host.h"
00099 #include "misc.h"
00100 #include "config.h"
00101 #include "endian.h"
00102
00103
00104
00105
00106
00107
00108
00109 #define TARGET_PISA
00110
00111 #ifndef TARGET_PISA_BIG
00112 #ifndef TARGET_PISA_LITTLE
00113
00114 #ifdef BYTES_BIG_ENDIAN
00115 #define TARGET_PISA_BIG
00116 #else
00117 #define TARGET_PISA_LITTLE
00118 #endif
00119 #endif
00120 #endif
00121
00122
00123 #if defined(BYTES_BIG_ENDIAN) && defined(TARGET_PISA_LITTLE)
00124 #define MD_CROSS_ENDIAN
00125 #endif
00126 #if defined(BYTES_LITTLE_ENDIAN) && defined(TARGET_PISA_BIG)
00127 #define MD_CROSS_ENDIAN
00128 #endif
00129
00130
00131 #define NA 0
00132
00133
00134
00135
00136
00137
00138 #undef MD_QWORD_ADDRS
00139
00140
00141 typedef word_t md_addr_t;
00142
00143
00144
00145
00146
00147
00148
00149 #define MD_PAGE_SIZE 4096
00150 #define MD_LOG_PAGE_SIZE 12
00151
00152
00153
00154
00155
00156
00157 enum md_fault_type {
00158 md_fault_none = 0,
00159 md_fault_access,
00160 md_fault_alignment,
00161 md_fault_overflow,
00162 md_fault_div0,
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 3
00181
00182
00183 #define MD_TOTAL_REGS \
00184 (32 + 32 + 3 + 1 + 1 + 1)
00185
00186
00187 typedef sword_t md_gpr_t[MD_NUM_IREGS];
00188
00189
00190 typedef union {
00191 sword_t l[MD_NUM_FREGS];
00192 sfloat_t f[MD_NUM_FREGS];
00193 dfloat_t d[MD_NUM_FREGS/2];
00194 } md_fpr_t;
00195
00196
00197 typedef struct {
00198 sword_t hi, lo;
00199 int fcc;
00200 } md_ctrl_t;
00201
00202
00203 enum md_reg_names {
00204 MD_REG_ZERO = 0,
00205 MD_REG_GP = 28,
00206 MD_REG_SP = 29,
00207 MD_REG_FP = 30
00208 };
00209
00210
00211
00212
00213
00214
00215
00216 typedef struct {
00217 word_t a;
00218 word_t b;
00219 } md_inst_t;
00220
00221
00222 extern md_inst_t MD_NOP_INST;
00223
00224
00225 #ifdef MD_CROSS_ENDIAN
00226
00227 #define MD_SWAPH(X) SWAP_HALF(X)
00228 #define MD_SWAPW(X) SWAP_WORD(X)
00229 #define MD_SWAPQ(X) SWAP_QWORD(X)
00230 #define MD_SWAPI(X) ((X).a = SWAP_WORD((X).a), \
00231 (X).b = SWAP_WORD((X).b))
00232
00233 #else
00234
00235 #define MD_SWAPH(X) (X)
00236 #define MD_SWAPW(X) (X)
00237 #define MD_SWAPQ(X) (X)
00238 #define MD_SWAPD(X) (X)
00239 #define MD_SWAPI(X) (X)
00240
00241 #endif
00242
00243
00244 #define MD_FETCH_INST(INST, MEM, PC) \
00245 { inst.a = MEM_READ_WORD(mem, regs.regs_PC); \
00246 inst.b = MEM_READ_WORD(mem, regs.regs_PC + sizeof(word_t)); }
00247
00248
00249
00250
00251
00252
00253 #define MD_TEXT_BASE 0x00400000
00254 #define MD_DATA_BASE 0x10000000
00255 #define MD_STACK_BASE 0x7fffc000
00256
00257
00258 #define MD_MAX_ENVIRON 16384
00259
00260
00261
00262
00263
00264
00265
00266 #define MD_OPFIELD(INST) (INST.a & 0xff)
00267 #define MD_SET_OPCODE(OP, INST) ((OP) = ((INST).a & 0xff))
00268
00269
00270
00271 #define MD_MAX_MASK 255
00272
00273
00274 enum md_opcode {
00275 OP_NA = 0,
00276 #define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3) OP,
00277 #define DEFLINK(OP,MSK,NAME,MASK,SHIFT) OP,
00278 #define CONNECT(OP)
00279 #include "machine.def"
00280 OP_MAX
00281 };
00282
00283
00284 #define MD_OP_ENUM(MSK) (md_mask2op[MSK])
00285 extern enum md_opcode md_mask2op[];
00286
00287
00288 #define MD_OP_NAME(OP) (md_op2name[OP])
00289 extern char *md_op2name[];
00290
00291
00292 #define MD_OP_FORMAT(OP) (md_op2format[OP])
00293 extern char *md_op2format[];
00294
00295
00296 enum md_fu_class {
00297 FUClass_NA = 0,
00298 IntALU,
00299 IntMULT,
00300 IntDIV,
00301 FloatADD,
00302 FloatCMP,
00303 FloatCVT,
00304 FloatMULT,
00305 FloatDIV,
00306 FloatSQRT,
00307 RdPort,
00308 WrPort,
00309 NUM_FU_CLASSES
00310 };
00311
00312
00313 #define MD_OP_FUCLASS(OP) (md_op2fu[OP])
00314 extern enum md_fu_class md_op2fu[];
00315
00316
00317 #define MD_FU_NAME(FU) (md_fu2name[FU])
00318 extern char *md_fu2name[];
00319
00320
00321 #define F_ICOMP 0x00000001
00322 #define F_FCOMP 0x00000002
00323 #define F_CTRL 0x00000004
00324 #define F_UNCOND 0x00000008
00325 #define F_COND 0x00000010
00326 #define F_MEM 0x00000020
00327 #define F_LOAD 0x00000040
00328 #define F_STORE 0x00000080
00329 #define F_DISP 0x00000100
00330 #define F_RR 0x00000200
00331 #define F_DIRECT 0x00000400
00332 #define F_TRAP 0x00000800
00333 #define F_LONGLAT 0x00001000
00334 #define F_DIRJMP 0x00002000
00335 #define F_INDIRJMP 0x00004000
00336 #define F_CALL 0x00008000
00337 #define F_FPCOND 0x00010000
00338 #define F_IMM 0x00020000
00339
00340
00341 #define MD_OP_FLAGS(OP) (md_op2flags[OP])
00342 extern unsigned int md_op2flags[];
00343
00344
00345 #undef RS
00346 #define RS (inst.b >> 24)
00347 #define RT ((inst.b >> 16) & 0xff)
00348 #define RD ((inst.b >> 8) & 0xff)
00349
00350
00351 #define SHAMT (inst.b & 0xff)
00352
00353
00354 #define FS RS
00355 #define FT RT
00356 #define FD RD
00357
00358
00359 #define IMM ((int)((short)(inst.b & 0xffff)))
00360
00361
00362 #define UIMM (inst.b & 0xffff)
00363
00364
00365 #define TARG (inst.b & 0x3ffffff)
00366
00367
00368 #define BCODE (inst.b & 0xfffff)
00369
00370
00371 #define OFS IMM
00372
00373
00374 #define BS RS
00375
00376
00377 #define MAXINT_VAL 0x7fffffff
00378
00379
00380 #define OVER(X,Y) \
00381 ((((X) > 0) && ((Y) > 0) && (MAXINT_VAL - (X) < (Y))) \
00382 || (((X) < 0) && ((Y) < 0) && (-MAXINT_VAL - (X) > (Y))))
00383
00384
00385 #define UNDER(X,Y) \
00386 ((((X) > 0) && ((Y) < 0) && (MAXINT_VAL + (Y) < (X))) \
00387 || (((X) < 0) && ((Y) > 0) && (-MAXINT_VAL + (Y) > (X))))
00388
00389
00390 #ifndef SET_TPC
00391 #define SET_TPC(PC) (void)0
00392 #endif
00393
00394 #ifdef BYTES_BIG_ENDIAN
00395
00396 #define WL_SIZE(ADDR) ((ADDR) & 0x03)
00397 #define WL_BASE(ADDR) ((ADDR) & ~0x03)
00398 #define WL_PROT_MASK(ADDR) (md_lr_masks[4-WL_SIZE(ADDR)])
00399 #define WL_PROT_MASK1(ADDR) (md_lr_masks[WL_SIZE(ADDR)])
00400 #define WL_PROT_MASK2(ADDR) (md_lr_masks[4-WL_SIZE(ADDR)])
00401
00402
00403 #define WR_SIZE(ADDR) (((ADDR) & 0x03)+1)
00404 #define WR_BASE(ADDR) ((ADDR) & ~0x03)
00405 #define WR_PROT_MASK(ADDR) (~(md_lr_masks[WR_SIZE(ADDR)]))
00406 #define WR_PROT_MASK1(ADDR) ((md_lr_masks[WR_SIZE(ADDR)]))
00407 #define WR_PROT_MASK2(ADDR) (md_lr_masks[4-WR_SIZE(ADDR)])
00408 #else
00409
00410 #define WL_SIZE(ADDR) (4-((ADDR) & 0x03))
00411 #define WL_BASE(ADDR) ((ADDR) & ~0x03)
00412 #define WL_PROT_MASK(ADDR) (md_lr_masks[4-WL_SIZE(ADDR)])
00413 #define WL_PROT_MASK1(ADDR) (md_lr_masks[WL_SIZE(ADDR)])
00414 #define WL_PROT_MASK2(ADDR) (md_lr_masks[4-WL_SIZE(ADDR)])
00415
00416
00417 #define WR_SIZE(ADDR) (((ADDR) & 0x03)+1)
00418 #define WR_BASE(ADDR) ((ADDR) & ~0x03)
00419 #define WR_PROT_MASK(ADDR) (~(md_lr_masks[WR_SIZE(ADDR)]))
00420 #define WR_PROT_MASK1(ADDR) ((md_lr_masks[WR_SIZE(ADDR)]))
00421 #define WR_PROT_MASK2(ADDR) (md_lr_masks[4-WR_SIZE(ADDR)])
00422 #endif
00423
00424
00425 extern word_t md_lr_masks[];
00426
00427 #if 0
00428
00429 #define WL_SIZE(ADDR) (4-((ADDR) & 0x03))
00430 #define WL_BASE(ADDR) ((ADDR) & ~0x03)
00431 #define WL_PROT_MASK(ADDR) (md_lr_masks[4-WL_SIZE(ADDR)])
00432
00433
00434 #define WR_SIZE(ADDR) (((ADDR) & 0x03)+1)
00435 #define WR_BASE(ADDR) ((ADDR) & ~0x03)
00436 #define WR_PROT_MASK(ADDR) (~(md_lr_masks[WR_SIZE(ADDR)]))
00437
00438
00439 #define WL_SIZE(ADDR) ((ADDR) & 0x03)
00440 #define WL_BASE(ADDR) ((ADDR) & ~0x03)
00441 #define WL_PROT_MASK1(ADDR) (md_lr_masks[WL_SIZE(ADDR)])
00442 #define WL_PROT_MASK2(ADDR) (md_lr_masks[4-WL_SIZE(ADDR)])
00443
00444
00445 #define WR_SIZE(ADDR) (((ADDR) & 0x03)+1)
00446 #define WR_BASE(ADDR) ((ADDR) & ~0x03)
00447 #define WR_PROT_MASK1(ADDR) ((md_lr_masks[WR_SIZE(ADDR)]))
00448 #define WR_PROT_MASK2(ADDR) (md_lr_masks[4-WR_SIZE(ADDR)])
00449 #endif
00450
00451
00452
00453
00454
00455
00456
00457 #define SS_SYS_exit 1
00458 #define MD_EXIT_SYSCALL(REGS) ((REGS)->regs_R[2] == SS_SYS_exit)
00459
00460
00461 #define SS_SYS_write 4
00462 #define MD_OUTPUT_SYSCALL(REGS) \
00463 ((REGS)->regs_R[2] == SS_SYS_write \
00464 && ((REGS)->regs_R[4] == 1 \
00465 || (REGS)->regs_R[4] == 2))
00466
00467
00468 #define MD_STREAM_FILENO(REGS) ((REGS)->regs_R[4])
00469
00470
00471 #define MD_IS_CALL(OP) \
00472 ((MD_OP_FLAGS(OP) & (F_CTRL|F_CALL)) == (F_CTRL|F_CALL))
00473
00474
00475 #define MD_IS_RETURN(OP) ((OP) == JR && (RS) == 31)
00476
00477
00478 #define MD_IS_INDIR(OP) ((OP) == JR)
00479
00480
00481 enum md_amode_type {
00482 md_amode_imm,
00483 md_amode_gp,
00484 md_amode_sp,
00485 md_amode_fp,
00486 md_amode_disp,
00487 md_amode_rr,
00488 md_amode_NUM
00489 };
00490 extern char *md_amode_str[md_amode_NUM];
00491
00492
00493 #define MD_AMODE_PREPROBE(OP, FSM) \
00494 { if ((OP) == LUI) (FSM) = (RT); }
00495
00496
00497 #define MD_AMODE_PROBE(AM, OP, FSM) \
00498 { \
00499 if (MD_OP_FLAGS(OP) & F_DISP) \
00500 { \
00501 if ((BS) == (FSM)) \
00502 (AM) = md_amode_imm; \
00503 else if ((BS) == MD_REG_GP) \
00504 (AM) = md_amode_gp; \
00505 else if ((BS) == MD_REG_SP) \
00506 (AM) = md_amode_sp; \
00507 else if ((BS) == MD_REG_FP) \
00508 (AM) = md_amode_fp; \
00509 else \
00510 (AM) = md_amode_disp; \
00511 } \
00512 else if (MD_OP_FLAGS(OP) & F_RR) \
00513 (AM) = md_amode_rr; \
00514 else \
00515 panic("cannot decode addressing mode"); \
00516 }
00517
00518
00519 #define MD_AMODE_POSTPROBE(FSM) \
00520 { (FSM) = MD_REG_ZERO; }
00521
00522
00523
00524
00525
00526
00527
00528 #define MD_EIO_FILE_FORMAT EIO_PISA_FORMAT
00529
00530 #define MD_MISC_REGS_TO_EXO(REGS) \
00531 exo_new(ec_list, \
00532 exo_new(ec_integer, (exo_integer_t)sim_num_insn), \
00533 exo_new(ec_address, (exo_integer_t)(REGS)->regs_PC), \
00534 exo_new(ec_address, (exo_integer_t)(REGS)->regs_NPC), \
00535 exo_new(ec_integer, (exo_integer_t)(REGS)->regs_C.hi), \
00536 exo_new(ec_integer, (exo_integer_t)(REGS)->regs_C.lo), \
00537 exo_new(ec_integer, (exo_integer_t)(REGS)->regs_C.fcc),\
00538 NULL)
00539
00540 #define MD_IREG_TO_EXO(REGS, IDX) \
00541 exo_new(ec_address, (exo_integer_t)(REGS)->regs_R[IDX])
00542
00543 #define MD_FREG_TO_EXO(REGS, IDX) \
00544 exo_new(ec_address, (exo_integer_t)(REGS)->regs_F.l[IDX])
00545
00546 #define MD_EXO_TO_MISC_REGS(EXO, ICNT, REGS) \
00547 \
00548 if (!exo \
00549 || exo->ec != ec_list \
00550 || !exo->as_list.head \
00551 || exo->as_list.head->ec != ec_integer \
00552 || !exo->as_list.head->next \
00553 || exo->as_list.head->next->ec != ec_address \
00554 || !exo->as_list.head->next->next \
00555 || exo->as_list.head->next->next->ec != ec_address \
00556 || !exo->as_list.head->next->next->next \
00557 || exo->as_list.head->next->next->next->ec != ec_integer \
00558 || !exo->as_list.head->next->next->next->next \
00559 || exo->as_list.head->next->next->next->next->ec != ec_integer \
00560 || !exo->as_list.head->next->next->next->next->next \
00561 || exo->as_list.head->next->next->next->next->next->ec != ec_integer\
00562 || exo->as_list.head->next->next->next->next->next->next != NULL) \
00563 fatal("could not read EIO misc regs"); \
00564 (ICNT) = (counter_t)exo->as_list.head->as_integer.val; \
00565 (REGS)->regs_PC = (md_addr_t)exo->as_list.head->next->as_integer.val; \
00566 (REGS)->regs_NPC = \
00567 (md_addr_t)exo->as_list.head->next->next->as_integer.val; \
00568 (REGS)->regs_C.hi = \
00569 (word_t)exo->as_list.head->next->next->next->as_integer.val; \
00570 (REGS)->regs_C.lo = \
00571 (word_t)exo->as_list.head->next->next->next->next->as_integer.val; \
00572 (REGS)->regs_C.fcc = \
00573 (int)exo->as_list.head->next->next->next->next->next->as_integer.val;
00574
00575 #define MD_EXO_TO_IREG(EXO, REGS, IDX) \
00576 ((REGS)->regs_R[IDX] = (word_t)(EXO)->as_integer.val)
00577
00578 #define MD_EXO_TO_FREG(EXO, REGS, IDX) \
00579 ((REGS)->regs_F.l[IDX] = (word_t)(EXO)->as_integer.val)
00580
00581 #define MD_EXO_CMP_IREG(EXO, REGS, IDX) \
00582 ((REGS)->regs_R[IDX] != (sword_t)(EXO)->as_integer.val)
00583
00584 #define MD_FIRST_IN_REG 2
00585 #define MD_LAST_IN_REG 7
00586
00587 #define MD_FIRST_OUT_REG 2
00588 #define MD_LAST_OUT_REG 7
00589
00590
00591
00592
00593
00594
00595
00596 typedef word_t exo_address_t;
00597
00598
00599 typedef qword_t exo_integer_t;
00600
00601
00602 typedef double exo_float_t;
00603
00604
00605
00606
00607
00608
00609
00610 #ifdef HOST_HAS_QWORD
00611 #define stat_reg_counter stat_reg_sqword
00612 #define sc_counter sc_sqword
00613 #define for_counter for_sqword
00614 #else
00615 #define stat_reg_counter stat_reg_double
00616 #define sc_counter sc_double
00617 #define for_counter for_double
00618 #endif
00619
00620
00621 #define stat_reg_addr stat_reg_uint
00622
00623
00624
00625
00626
00627
00628
00629 enum md_reg_type {
00630 rt_gpr,
00631 rt_lpr,
00632 rt_fpr,
00633 rt_dpr,
00634 rt_ctrl,
00635 rt_PC,
00636 rt_NPC,
00637 rt_NUM
00638 };
00639
00640
00641 struct md_reg_names_t {
00642 char *str;
00643 enum md_reg_type file;
00644 int reg;
00645 };
00646
00647
00648 extern struct md_reg_names_t md_reg_names[];
00649
00650
00651 char *md_reg_name(enum md_reg_type rt, int reg);
00652
00653
00654 struct eval_value_t;
00655 struct regs_t;
00656 char *
00657 md_reg_obj(struct regs_t *regs,
00658 int is_write,
00659 enum md_reg_type rt,
00660 int reg,
00661 struct eval_value_t *val);
00662
00663
00664 void md_print_ireg(md_gpr_t regs, int reg, FILE *stream);
00665 void md_print_iregs(md_gpr_t regs, FILE *stream);
00666
00667
00668 void md_print_fpreg(md_fpr_t regs, int reg, FILE *stream);
00669 void md_print_fpregs(md_fpr_t regs, FILE *stream);
00670
00671
00672 void md_print_creg(md_ctrl_t regs, int reg, FILE *stream);
00673 void md_print_cregs(md_ctrl_t regs, FILE *stream);
00674
00675
00676 word_t md_crc_regs(struct regs_t *regs);
00677
00678
00679 word_t md_xor_regs(struct regs_t *regs);
00680
00681
00682
00683
00684
00685
00686
00687 #define MD_AGEN_OP ADD
00688
00689
00690 #define MD_NOP_OP NOP
00691
00692
00693
00694 #define MD_VALID_ADDR(ADDR) \
00695 (((ADDR) >= ld_text_base && (ADDR) < (ld_text_base + ld_text_size)) \
00696 || ((ADDR) >= ld_data_base && (ADDR) < ld_stack_base))
00697
00698
00699
00700
00701
00702
00703
00704
00705 #define MD_BR_SHIFT 3
00706
00707
00708
00709
00710
00711
00712
00713 void md_init_decoder(void);
00714
00715
00716 void
00717 md_print_insn(md_inst_t inst,
00718 md_addr_t pc,
00719 FILE *stream);
00720
00721 #endif
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739 #if 0
00740
00741
00742 #define SS_PAGE_SIZE 4096
00743
00744
00745 #define SS_NUM_REGS 32
00746
00747
00748 #define SS_TOTAL_REGS \
00749 (SS_NUM_REGS+SS_NUM_REGS+1+1+1+1+ \
00750 1+1)
00751
00752
00753 #define SS_COMP_OP ((inst.a & 0xff00) >> 8)
00754
00755
00756 #define SS_COMP_NOP 0x00
00757 #define SS_COMP_POST_INC 0x01
00758 #define SS_COMP_POST_DEC 0x02
00759 #define SS_COMP_PRE_INC 0x03
00760 #define SS_COMP_PRE_DEC 0x04
00761 #define SS_COMP_POST_DBL_INC 0x05
00762 #define SS_COMP_POST_DBL_DEC 0x06
00763 #define SS_COMP_PRE_DBL_INC 0x07
00764 #define SS_COMP_PRE_DBL_DEC 0x08
00765
00766
00767
00768
00769
00770
00771 #define INC_DEC(EXPR, REG, SIZE) \
00772 (SET_GPR((REG), GPR(REG) + ss_fore_tab[(SIZE)-1][SS_COMP_OP]), \
00773 (EXPR), \
00774 SET_GPR((REG), GPR(REG) + ss_aft_tab[(SIZE)-1][SS_COMP_OP]))
00775
00776
00777 extern int ss_fore_tab[8][5];
00778 extern int ss_aft_tab[8][5];
00779
00780
00781 #define Rgp 28
00782 #define Rsp 29
00783 #define Rfp 30
00784
00785
00786 extern SS_ADDR_TYPE ss_lr_temp;
00787
00788
00789 extern SS_ADDR_TYPE temp_bs, temp_rd;
00790
00791
00792
00793
00794
00795 #ifndef IFAIL
00796 #define IFAIL(S) fatal(S)
00797 #endif
00798
00799
00800 #define DIV0(N) (((N) == 0) ? IFAIL("divide by 0") : (void)0)
00801
00802
00803 #define INTALIGN(N) (((N) & 01) \
00804 ? IFAIL("bad INT register alignment") : (void)0)
00805
00806
00807 #define FPALIGN(N) (((N) & 01) \
00808 ? IFAIL("bad FP register alignment") : (void)0)
00809
00810
00811 #define TALIGN(TARG) (((TARG) & 0x7) \
00812 ? IFAIL("bad jump alignment") : (void)0)
00813
00814 #define OVER(X,Y) ((void)0)
00815 #define UNDER(X,Y) ((void)0)
00816 #define DIV0(N) ((void)0)
00817 #define INTALIGN(N) ((void)0)
00818 #define FPALIGN(N) ((void)0)
00819 #define TALIGN(TARG) ((void)0)
00820
00821
00822
00823
00824 #define IDIV(A, B) ((A) / (B))
00825 #define IMOD(A, B) ((A) % (B))
00826 #define FDIV(A, B) ((A) / (B))
00827 #define FINT(A) ((int)A)
00828
00829 #endif