📄 ppc-instructions
字号:
busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]); busy_ptr->spr_busy = nSPR; model_ptr->spr_busy[nSPR] = 1; busy_ptr->nr_writebacks = 1; TRACE(trace_model,("Making register %s busy.\n", spr_name(nSPR)));# Schedule a MFCR instruction that moves the CR into an integer regsitervoid::model-function::ppc_insn_mfcr:itable_index index, model_data *model_ptr, unsigned32 int_mask const unsigned32 cr_mask = 0xff; model_busy *busy_ptr; while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) { if (WITH_TRACE && ppc_trace[trace_model]) model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR); model_ptr->nr_stalls_data++; model_new_cycle(model_ptr); } busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]); model_ptr->int_busy |= int_mask; busy_ptr->int_busy |= int_mask; busy_ptr->nr_writebacks = 1; if (WITH_TRACE && ppc_trace[trace_model]) model_trace_make_busy(model_ptr, int_mask, 0, 0);# Schedule a MTCR instruction that moves an integer register into the CRvoid::model-function::ppc_insn_mtcr:itable_index index, model_data *model_ptr, unsigned32 int_mask, unsigned FXM int f; int nr_crs = 0; unsigned32 cr_mask = 0; const model_time *normal_time = &model_ptr->timing[index]; static const model_time ppc604_1bit_time = { PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 }; model_busy *busy_ptr; for (f = 0; f < 8; f++) { if (FXM & (0x80 >> f)) { cr_mask |= (1 << f); nr_crs++; } } while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) { if (WITH_TRACE && ppc_trace[trace_model]) model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR); model_ptr->nr_stalls_data++; model_new_cycle(model_ptr); } /* If only one CR is being moved, use the SCIU, not the MCIU on the 604 */ if (CURRENT_MODEL == MODEL_ppc604 && nr_crs == 1) { normal_time = &ppc604_1bit_time; } busy_ptr = model_wait_for_unit(index, model_ptr, normal_time); busy_ptr->cr_fpscr_busy |= cr_mask; model_ptr->cr_fpscr_busy |= cr_mask; model_ptr->nr_mtcrf_crs[nr_crs]++; busy_ptr->nr_writebacks = 1; if (WITH_TRACE && ppc_trace[trace_model]) model_trace_make_busy(model_ptr, 0, 0, cr_mask);model_data *::model-function::model_create:cpu *processor model_data *model_ptr = ZALLOC(model_data); model_ptr->name = model_name[CURRENT_MODEL]; model_ptr->timing = model_time_mapping[CURRENT_MODEL]; model_ptr->processor = processor; model_ptr->nr_cycles = 1; model_ptr->busy_tail = &model_ptr->busy_head; switch (CURRENT_MODEL) { case MODEL_ppc601: model_ptr->max_nr_writebacks = 1; break; /* ??? */ case MODEL_ppc603: model_ptr->max_nr_writebacks = 2; break; case MODEL_ppc603e: model_ptr->max_nr_writebacks = 2; break; case MODEL_ppc604: model_ptr->max_nr_writebacks = 2; break; default: error ("Unknown model %d\n", CURRENT_MODEL); } return model_ptr;void::model-function::model_init:model_data *model_ptrvoid::model-function::model_halt:model_data *model_ptr /* Let pipeline drain */ while (model_ptr->busy_head.next) model_new_cycle(model_ptr);unsigned_word::model-function::model_get_number_of_stalls:model_data *model_ptr return (model_ptr->nr_stalls_data + model_ptr->nr_stalls_unit + model_ptr->nr_stalls_serialize + model_ptr->nr_stalls_writeback);unsigned_word::model-function::model_get_number_of_cycles:model_data *model_ptr return (model_ptr->nr_cycles);model_print *::model-function::model_mon_info:model_data *model_ptr model_print *head; model_print *tail; ppc_function_unit i; count_type nr_insns; int j; head = tail = ZALLOC(model_print); tail->count = model_ptr->nr_cycles; tail->name = "cycle"; tail->suffix_plural = "s"; tail->suffix_singular = ""; if (model_ptr->nr_stalls_data) { tail->next = ZALLOC(model_print); tail = tail->next; tail->count = model_ptr->nr_stalls_data; tail->name = "stall"; tail->suffix_plural = "s waiting for data"; tail->suffix_singular = " waiting for data"; } if (model_ptr->nr_stalls_unit) { tail->next = ZALLOC(model_print); tail = tail->next; tail->count = model_ptr->nr_stalls_unit; tail->name = "stall"; tail->suffix_plural = "s waiting for a function unit"; tail->suffix_singular = " waiting for a function unit"; } if (model_ptr->nr_stalls_serialize) { tail->next = ZALLOC(model_print); tail = tail->next; tail->count = model_ptr->nr_stalls_serialize; tail->name = "stall"; tail->suffix_plural = "s waiting for serialization"; tail->suffix_singular = " waiting for serialization"; } if (model_ptr->nr_stalls_writeback) { tail->next = ZALLOC(model_print); tail = tail->next; tail->count = model_ptr->nr_stalls_writeback; tail->name = ""; tail->suffix_plural = "times a write-back slot was unavailable"; tail->suffix_singular = "time a writeback was unavailable"; } if (model_ptr->nr_branches) { tail->next = ZALLOC(model_print); tail = tail->next; tail->count = model_ptr->nr_branches; tail->name = "branch"; tail->suffix_plural = "es"; tail->suffix_singular = ""; } if (model_ptr->nr_branches_fallthrough) { tail->next = ZALLOC(model_print); tail = tail->next; tail->count = model_ptr->nr_branches_fallthrough; tail->name = "conditional branch"; tail->suffix_plural = "es fell through"; tail->suffix_singular = " fell through"; } if (model_ptr->nr_branch_predict_trues) { tail->next = ZALLOC(model_print); tail = tail->next; tail->count = model_ptr->nr_branch_predict_trues; tail->name = "successful branch prediction"; tail->suffix_plural = "s"; tail->suffix_singular = ""; } if (model_ptr->nr_branch_predict_falses) { tail->next = ZALLOC(model_print); tail = tail->next; tail->count = model_ptr->nr_branch_predict_falses; tail->name = "unsuccessful branch prediction"; tail->suffix_plural = "s"; tail->suffix_singular = ""; } for (j = 0; j < (sizeof(ppc_branch_conditional_name) / sizeof(ppc_branch_conditional_name[0])) ; j++) { if (model_ptr->nr_branch_conditional[j]) { tail->next = ZALLOC(model_print); tail = tail->next; tail->count = model_ptr->nr_branch_conditional[j]; tail->name = ppc_branch_conditional_name[j]; tail->suffix_plural = " conditional branches"; tail->suffix_singular = " conditional branch"; } } for (j = 0; j < 9; j++) { if (model_ptr->nr_mtcrf_crs[j]) { tail->next = ZALLOC(model_print); tail = tail->next; tail->count = model_ptr->nr_mtcrf_crs[j]; tail->name = ppc_nr_mtcrf_crs[j]; tail->suffix_plural = " instructions"; tail->suffix_singular = " instruction"; } } nr_insns = 0; for (i = PPC_UNIT_BAD; i < nr_ppc_function_units; i++) { if (model_ptr->nr_units[i]) { nr_insns += model_ptr->nr_units[i]; tail->next = ZALLOC(model_print); tail = tail->next; tail->count = model_ptr->nr_units[i]; tail->name = ppc_function_unit_name[i]; tail->suffix_plural = "s"; tail->suffix_singular = ""; } } tail->next = ZALLOC(model_print); tail = tail->next; tail->count = nr_insns; tail->name = "instruction"; tail->suffix_plural = "s that were accounted for in timing info"; tail->suffix_singular = " that was accounted for in timing info"; tail->next = (model_print *)0; return head;void::model-function::model_mon_info_free:model_data *model_ptr, model_print *ptr while (ptr) { model_print *next = ptr->next; free((void *)ptr); ptr = next; }void::model-function::model_branches:model_data *model_ptr, int failed, int conditional model_ptr->nr_units[PPC_UNIT_BPU]++; if (failed) model_ptr->nr_branches_fallthrough++; else model_ptr->nr_branches++; if (conditional >= 0) model_ptr->nr_branch_conditional[conditional]++; model_new_cycle(model_ptr); /* A branch always ends the current cycle */void::model-function::model_branch_predict:model_data *model_ptr, int success if (success) model_ptr->nr_branch_predict_trues++; else model_ptr->nr_branch_predict_falses++;# The following (illegal) instruction is `known' by gen and is# called when ever an illegal instruction is encountered::internal::illegal program_interrupt(processor, cia, illegal_instruction_program_interrupt);# The following (floating point unavailable) instruction is `known' by gen# and is called when ever an a floating point instruction is to be# executed but floating point is make unavailable by the MSR::internal::floating_point_unavailable floating_point_unavailable_interrupt(processor, cia);## Floating point support functions## Convert 32bit single to 64bit doubleunsigned64::function::DOUBLE:unsigned32 WORD unsigned64 FRT; if (EXTRACTED32(WORD, 1, 8) > 0 && EXTRACTED32(WORD, 1, 8) < 255) { /* normalized operand */ int not_word_1_1 = !EXTRACTED32(WORD, 1, 1); /*2.6.3 bug*/ FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1) | INSERTED64(not_word_1_1, 2, 2) | INSERTED64(not_word_1_1, 3, 3) | INSERTED64(not_word_1_1, 4, 4) | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29))); } else if (EXTRACTED32(WORD, 1, 8) == 0 && EXTRACTED32(WORD, 9, 31) != 0) { /* denormalized operand */ int sign = EXTRACTED32(WORD, 0, 0); int exp = -126; unsigned64 frac = INSERTED64(EXTRACTED32(WORD, 9, 31), 1, (52 - 29)); /* normalize the operand */ while (MASKED64(frac, 0, 0) == 0) { frac <<= 1; exp -= 1; } FRT = (INSERTED64(sign, 0, 0) | INSERTED64(exp + 1023, 1, 11) | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63)); } else if (EXTRACTED32(WORD, 1, 8) == 255 || EXTRACTED32(WORD, 1, 31) == 0) { FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1) | INSERTED64(EXTRACTED32(WORD, 1, 1), 2, 2) | INSERTED64(EXTRACTED32(WORD, 1, 1), 3, 3) | INSERTED64(EXTRACTED32(WORD, 1, 1), 4, 4) | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29))); } else { error("DOUBLE - unknown case\n"); FRT = 0; } return FRT;# Convert 64bit single to 32bit doubleunsigned32::function::SINGLE:unsigned64 FRS unsigned32 WORD; if (EXTRACTED64(FRS, 1, 11) > 896 || EXTRACTED64(FRS, 1, 63) == 0) { /* no denormalization required (includes Zero/Infinity/NaN) */ WORD = (INSERTED32(EXTRACTED64(FRS, 0, 1), 0, 1) | INSERTED32(EXTRACTED64(FRS, 5, 34), 2, 31)); } else if (874 <= EXTRACTED64(FRS, 1, 11) && EXTRACTED64(FRS, 1, 11) <= 896) { /* denormalization required */ int sign = EXTRACTED64(FRS, 0, 0); int exp = EXTRACTED64(FRS, 1, 11) - 1023; unsigned64 frac = (BIT64(0) | INSERTED64(EXTRACTED64(FRS, 12, 63), 1, 52)); /* denormalize the operand */ while (exp < -126) { frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63); exp += 1; } WORD = (INSERTED32(sign, 0, 0) | INSERTED32(0x00, 1, 8) | INSERTED32(EXTRACTED64(frac, 1, 23), 9, 31)); } else { WORD = 0x0; /* ??? */ } return WORD;# round 64bit double to 64bit but singlevoid::function::Round_Single:cpu *processor, int sign, int *exp, unsigned64 *frac_grx /* comparisons ignore u bits */ unsigned64 out; int inc = 0; int lsb = EXTRACTED64(*frac_grx, 23, 23); int gbit = EXTRACTED64(*frac_grx, 24, 24); int rbit = EXTRACTED64(*frac_grx, 25, 25); int xbit = EXTRACTED64(*frac_grx, 26, 55) != 0; if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) { if (lsb == 1 && gbit == 1) inc = 1; if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1; if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1; } if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) { if (sign == 0 && gbit == 1) inc = 1; if (sign == 0 && rbit == 1) inc = 1; if (sign == 0 && xbit == 1) inc = 1; } if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) { if (sign == 1 && gbit == 1) inc = 1; if (sign == 1 && rbit == 1) inc = 1; if (sign == 1 && xbit == 1) inc = 1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -