📄 ppc-instructions
字号:
## This file is part of the program psim.## Copyright 1994, 1995, 1996, 1997, 2003, 2004 Andrew Cagney## --## The pseudo-code that appears below, translated into C, was copied# by Andrew Cagney of Moss Vale, Australia.## This pseudo-code is copied by permission from the publication# "The PowerPC Architecture: A Specification for A New Family of# RISC Processors" (ISBN 1-55860-316-6) copyright 1993, 1994 by# International Business Machines Corporation.## THIS PERMISSION IS PROVIDED WITHOUT WARRANTY OF ANY KIND, EITHER# EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.## --## This program is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 2 of the License, or# (at your option) any later version.## This program 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 General Public License for more details.## You should have received a copy of the GNU General Public License# along with this program; if not, write to the Free Software# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.#:cache::::RA:RA::cache:::signed_word *:rA:RA:(cpu_registers(processor)->gpr + RA):cache:::unsigned32:RA_BITMASK:RA:(1 << RA):compute:::int:RA_is_0:RA:(RA == 0):cache::::RT:RT::cache:::signed_word *:rT:RT:(cpu_registers(processor)->gpr + RT):cache:::unsigned32:RT_BITMASK:RT:(1 << RT):cache::::RS:RS::cache:::signed_word *:rS:RS:(cpu_registers(processor)->gpr + RS):cache:::unsigned32:RS_BITMASK:RS:(1 << RS):cache::::RB:RB::cache:::signed_word *:rB:RB:(cpu_registers(processor)->gpr + RB):cache:::unsigned32:RB_BITMASK:RB:(1 << RB):scratch::::FRA:FRA::cache:::unsigned64 *:frA:FRA:(cpu_registers(processor)->fpr + FRA):cache:::unsigned32:FRA_BITMASK:FRA:(1 << FRA):scratch::::FRB:FRB::cache:::unsigned64 *:frB:FRB:(cpu_registers(processor)->fpr + FRB):cache:::unsigned32:FRB_BITMASK:FRB:(1 << FRB):scratch::::FRC:FRC::cache:::unsigned64 *:frC:FRC:(cpu_registers(processor)->fpr + FRC):cache:::unsigned32:FRC_BITMASK:FRC:(1 << FRC):scratch::::FRS:FRS::cache:::unsigned64 *:frS:FRS:(cpu_registers(processor)->fpr + FRS):cache:::unsigned32:FRS_BITMASK:FRS:(1 << FRS):scratch::::FRT:FRT::cache:::unsigned64 *:frT:FRT:(cpu_registers(processor)->fpr + FRT):cache:::unsigned32:FRT_BITMASK:FRT:(1 << FRT):cache:::unsigned_word:EXTS_SI:SI:((signed_word)(signed16)instruction):scratch::::BI:BI::cache::::BIT32_BI:BI:BIT32(BI):cache::::BF:BF::cache:::unsigned32:BF_BITMASK:BF:(1 << BF):scratch::::BA:BA::cache::::BIT32_BA:BA:BIT32(BA):cache:::unsigned32:BA_BITMASK:BA:(1 << BA):scratch::::BB:BB::cache::::BIT32_BB:BB:BIT32(BB):cache:::unsigned32:BB_BITMASK:BB:(1 << BB):cache::::BT:BT::cache:::unsigned32:BT_BITMASK:BT:(1 << BT):cache:::unsigned_word:EXTS_BD_0b00:BD:(((signed_word)(signed16)instruction) & ~3):cache:::unsigned_word:EXTS_LI_0b00:LI:((((signed_word)(signed32)(instruction << 6)) >> 6) & ~0x3):cache:::unsigned_word:EXTS_D:D:((signed_word)(signed16)(instruction)):cache:::unsigned_word:EXTS_DS_0b00:DS:(((signed_word)(signed16)instruction) & ~0x3)#:compute:::int:SPR_is_256:SPR:(SPR == 256)# PowerPC models::model:604:ppc604: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0::model:603e:ppc603e:PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0::model:603:ppc603: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0::model:601:ppc601: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0# Flags for model.h::model-macro::: #define PPC_INSN_INT(OUT_MASK, IN_MASK, RC) \ do { \ if (CURRENT_MODEL_ISSUE > 0) { \ if (RC) \ ppc_insn_int_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, 1 << 0); \ else \ ppc_insn_int(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK); \ } \ } while (0) #define PPC_INSN_INT_CR(OUT_MASK, IN_MASK, CR_MASK) \ do { \ if (CURRENT_MODEL_ISSUE > 0) \ ppc_insn_int_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK); \ } while (0) #define PPC_INSN_CR(OUT_MASK, IN_MASK) \ do { \ if (CURRENT_MODEL_ISSUE > 0) \ ppc_insn_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK); \ } while (0) #define PPC_INSN_FLOAT(OUT_MASK, IN_MASK, RC) \ do { \ if (CURRENT_MODEL_ISSUE > 0) { \ if (RC) \ ppc_insn_float(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK); \ else \ ppc_insn_float_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, 1 << 0); \ } \ } while (0) #define PPC_INSN_FLOAT_CR(OUT_MASK, IN_MASK, CR_MASK) \ do { \ if (CURRENT_MODEL_ISSUE > 0) \ ppc_insn_float_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK); \ } while (0) #define PPC_INSN_INT_FLOAT(OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK) \ do { \ if (CURRENT_MODEL_ISSUE > 0) \ ppc_insn_int_float(MY_INDEX, cpu_model(processor), OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK); \ } while (0) #define PPC_INSN_FROM_SPR(INT_MASK, SPR) \ do { \ if (CURRENT_MODEL_ISSUE > 0) \ ppc_insn_from_spr(MY_INDEX, cpu_model(processor), INT_MASK, SPR); \ } while (0) #define PPC_INSN_TO_SPR(INT_MASK, SPR) \ do { \ if (CURRENT_MODEL_ISSUE > 0) \ ppc_insn_to_spr(MY_INDEX, cpu_model(processor), INT_MASK, SPR); \ } while (0) #define PPC_INSN_MFCR(INT_MASK) \ do { \ if (CURRENT_MODEL_ISSUE > 0) \ ppc_insn_mfcr(MY_INDEX, cpu_model(processor), INT_MASK); \ } while (0) #define PPC_INSN_MTCR(INT_MASK, FXM) \ do { \ if (CURRENT_MODEL_ISSUE > 0) \ ppc_insn_mtcr(MY_INDEX, cpu_model(processor), INT_MASK, FXM); \ } while (0)::model-data::: typedef enum _ppc_function_unit { PPC_UNIT_BAD, /* unknown function unit */ PPC_UNIT_IU, /* integer unit (601/603 style) */ PPC_UNIT_SRU, /* system register unit (601/603 style) */ PPC_UNIT_SCIU1, /* 1st single cycle integer unit (604 style) */ PPC_UNIT_SCIU2, /* 2nd single cycle integer unit (604 style) */ PPC_UNIT_MCIU, /* multiple cycle integer unit (604 style) */ PPC_UNIT_FPU, /* floating point unit */ PPC_UNIT_LSU, /* load/store unit */ PPC_UNIT_BPU, /* branch unit */ nr_ppc_function_units } ppc_function_unit; /* Structure to hold timing information on a per instruction basis */ struct _model_time { ppc_function_unit first_unit; /* first functional unit this insn could use */ ppc_function_unit second_unit; /* second functional unit this insn could use */ signed16 issue; /* # cycles before function unit can process other insns */ signed16 done; /* # cycles before insn is done */ unsigned32 flags; /* any flags that are needed */ }; /* Register mappings in status masks */ #define PPC_CR_REG 0 /* start of CR0 .. CR7 */ #define PPC_FPSCR_REG (PPC_CR_REG + 8) /* start of fpscr register */ #define PPC_NO_SPR (-1) /* flag for no SPR register */ /* Return if 1 bit set */ #define PPC_ONE_BIT_SET_P(x) (((x) & ((x)-1)) == 0) /* Structure for each functional unit that is busy */ typedef struct _model_busy model_busy; struct _model_busy { model_busy *next; /* next function unit */ ppc_function_unit unit; /* function unit name */ unsigned32 int_busy; /* int registers that are busy */ unsigned32 fp_busy; /* floating point registers that are busy */ unsigned32 cr_fpscr_busy; /* CR/FPSCR registers that are busy */ signed16 spr_busy; /* SPR register that is busy or PPC_NO_SPR */ unsigned32 vr_busy; /* AltiVec registers that are busy */ signed16 vscr_busy; /* AltiVec status register busy */ signed16 issue; /* # of cycles until unit can accept another insn */ signed16 done; /* # of cycles until insn is done */ signed16 nr_writebacks; /* # of registers this unit writes back */ }; /* Structure to hold the current state information for the simulated CPU model */ struct _model_data { cpu *processor; /* point back to processor */ const char *name; /* model name */ const model_time *timing; /* timing information */ model_busy busy_head; /* dummy entry to head list of busy function units */ model_busy *busy_tail; /* tail of list of busy function units */ model_busy *free_list; /* list of model_busy structs not in use */ count_type nr_cycles; /* # cycles */ count_type nr_branches; /* # branches */ count_type nr_branches_fallthrough; /* # conditional branches that fell through */ count_type nr_branch_predict_trues; /* # branches predicted correctly */ count_type nr_branch_predict_falses; /* # branches predicted incorrectly */ count_type nr_branch_conditional[32]; /* # of each type of bc */ count_type nr_mtcrf_crs[9]; /* # of CR's moved in a mtcrf instruction */ count_type nr_stalls_data; /* # of stalls for data */ count_type nr_stalls_unit; /* # of stalls waiting for a function unit */ count_type nr_stalls_serialize; /* # of stalls waiting for things to quiet down */ count_type nr_stalls_writeback; /* # of stalls waiting for a writeback slot */ count_type nr_units[nr_ppc_function_units]; /* function unit counts */ int max_nr_writebacks; /* max # of writeback slots available */ unsigned32 int_busy; /* int registers that are busy */ unsigned32 fp_busy; /* floating point registers that are busy */ unsigned32 cr_fpscr_busy; /* CR/FPSCR registers that are busy */ unsigned8 spr_busy[nr_of_sprs]; /* SPR registers that are busy */ unsigned32 vr_busy; /* AltiVec registers that are busy */ unsigned8 vscr_busy; /* AltiVec SC register busy */ unsigned8 busy[nr_ppc_function_units]; /* whether a function is busy or not */ }; static const char *const ppc_function_unit_name[ (int)nr_ppc_function_units ] = { "unknown functional unit instruction", "integer functional unit instruction", "system register functional unit instruction", "1st single cycle integer functional unit instruction", "2nd single cycle integer functional unit instruction", "multiple cycle integer functional unit instruction", "floating point functional unit instruction", "load/store functional unit instruction", "branch functional unit instruction", }; static const char *const ppc_branch_conditional_name[32] = { "branch if --CTR != 0 and condition is FALSE", /* 0000y */ "branch if --CTR != 0 and condition is FALSE, reverse branch likely", "branch if --CTR == 0 and condition is FALSE", /* 0001y */ "branch if --CTR == 0 and condition is FALSE, reverse branch likely", "branch if the condition is FALSE", /* 001zy */ "branch if the condition is FALSE, reverse branch likely", "branch if the condition is FALSE (ignored bit 1 set to 1)", /* 001zy */ "branch if the condition is FALSE, reverse branch likely (ignored bit 4 set to 1)", "branch if --CTR != 0 and condition is TRUE", /* 0100y */ "branch if --CTR != 0 and condition is TRUE, reverse branch likely", "branch if --CTR == 0 and condition is TRUE", /* 0101y */ "branch if --CTR == 0 and condition is TRUE, reverse branch likely", "branch if the condition is TRUE", /* 011zy */ "branch if the condition is TRUE, reverse branch likely", "branch if the condition is TRUE (ignored bit 1 set to 1)", /* 011zy */ "branch if the condition is TRUE, reverse branch likely (ignored bit 4 set to 1)", "branch if --CTR != 0", /* 1z00y */ "branch if --CTR != 0, reverse branch likely", "branch if --CTR == 0", /* 1z01y */ "branch if --CTR == 0, reverse branch likely", "branch always", /* 1z1zz */ "branch always (ignored bit 5 set to 1)", "branch always (ignored bit 4 set to 1)", /* 1z1zz */ "branch always (ignored bits 4,5 set to 1)", "branch if --CTR != 0 (ignored bit 1 set to 1)", /* 1z00y */ "branch if --CTR != 0, reverse branch likely (ignored bit 1 set to 1)", "branch if --CTR == 0 (ignored bit 1 set to 1)", /* 1z01y */ "branch if --CTR == 0, reverse branch likely (ignored bit 1 set to 1)", "branch always (ignored bit 1 set to 1)", /* 1z1zz */ "branch always (ignored bits 1,5 set to 1)", "branch always (ignored bits 1,4 set to 1)", /* 1z1zz */ "branch always (ignored bits 1,4,5 set to 1)", }; static const char *const ppc_nr_mtcrf_crs[9] = { "mtcrf moving 0 CRs", "mtcrf moving 1 CR", "mtcrf moving 2 CRs", "mtcrf moving 3 CRs", "mtcrf moving 4 CRs", "mtcrf moving 5 CRs", "mtcrf moving 6 CRs", "mtcrf moving 7 CRs", "mtcrf moving all CRs", };# Trace releasing resourcesvoid::model-static::model_trace_release:model_data *model_ptr, model_busy *busy int i; TRACE(trace_model,("done, %s, %d writeback%s\n", ppc_function_unit_name[busy->unit], busy->nr_writebacks, busy->nr_writebacks == 1 ? "" : "s")); if (busy->int_busy) { for(i = 0; i < 32; i++) { if (((1 << i) & busy->int_busy) != 0) { TRACE(trace_model, ("Register r%d is now available.\n", i)); } } } if (busy->fp_busy) { for(i = 0; i < 32; i++) { if (((1 << i) & busy->fp_busy) != 0) { TRACE(trace_model, ("Register f%d is now available.\n", i)); } } } if (busy->cr_fpscr_busy) { for(i = 0; i < 8; i++) { if (((1 << i) & busy->cr_fpscr_busy) != 0) { TRACE(trace_model, ("Register cr%d is now available.\n", i)); } } if (busy->cr_fpscr_busy & 0x100) TRACE(trace_model, ("Register fpscr is now available.\n")); } if (busy->spr_busy != PPC_NO_SPR) TRACE(trace_model, ("Register %s is now available.\n", spr_name(busy->spr_busy))); if (busy->vr_busy) { for(i = 0; i < 32; i++) { if (((1 << i) & busy->vr_busy) != 0) { TRACE(trace_model, ("Register v%d is now available.\n", i)); } } } if (busy->vscr_busy) TRACE(trace_model, ("VSCR Register is now available.\n", spr_name(busy->spr_busy)));# Trace making registers busyvoid::model-static::model_trace_make_busy:model_data *model_ptr, unsigned32 int_mask, unsigned32 fp_mask, unsigned32 cr_mask int i; if (int_mask) { for(i = 0; i < 32; i++) { if (((1 << i) & int_mask) != 0) { TRACE(trace_model, ("Register r%d is now busy.\n", i)); } } } if (fp_mask) { for(i = 0; i < 32; i++) { if (((1 << i) & fp_mask) != 0) { TRACE(trace_model, ("Register f%d is now busy.\n", i)); } } } if (cr_mask) { for(i = 0; i < 8; i++) { if (((1 << i) & cr_mask) != 0) { TRACE(trace_model, ("Register cr%d is now busy.\n", i)); } } }# Trace waiting for registers to become availablevoid::model-static::model_trace_busy_p:model_data *model_ptr, unsigned32 int_busy, unsigned32 fp_busy, unsigned32 cr_or_fpscr_busy, int spr_busy int i; if (int_busy) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -