diff options
author | Michael Meissner <gnu@the-meissners.org> | 1996-07-23 15:42:42 +0000 |
---|---|---|
committer | Michael Meissner <gnu@the-meissners.org> | 1996-07-23 15:42:42 +0000 |
commit | 30c87b55ec44de3a56cecf41fc7c93ed0c4005ca (patch) | |
tree | 5752ad56a8e4c990eb02b12f68d486415c79c41b /sim/ppc/ppc-instructions | |
parent | 856bcbcbbc01a252a8df2221038100e9a33f87ff (diff) | |
download | binutils-gdb-30c87b55ec44de3a56cecf41fc7c93ed0c4005ca.tar.gz |
New simulator changes from Andrew
Diffstat (limited to 'sim/ppc/ppc-instructions')
-rw-r--r-- | sim/ppc/ppc-instructions | 416 |
1 files changed, 221 insertions, 195 deletions
diff --git a/sim/ppc/ppc-instructions b/sim/ppc/ppc-instructions index 2ac13ab68ca..be626555670 100644 --- a/sim/ppc/ppc-instructions +++ b/sim/ppc/ppc-instructions @@ -1,7 +1,7 @@ # # This file is part of the program psim. # -# Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au> +# Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au> # # -- # @@ -33,38 +33,6 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # -# -- -# -# -# Fields: -# -# 1 Instruction format as a `start-bit,content' pairs. -# the content is one of a digit, field name or `/' (aka.0) -# -# 2 Format specifier -# -# 3 Flags: 64 - 64bit only -# f - floating point enabled required -# -# 4 short name -# -# 5 Description -# -# -# For flags marked 'model', the fields are interpreted as follows: -# -# 1 Not used -# -# 2 Not used -# -# 3 "macro" -# -# 4 String name for model -# -# 5 Specific CPU model, must be an identifier -# -# 6 Comma separated list of functional units - # PowerPC models ::model:604:ppc604: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0 @@ -78,68 +46,68 @@ do { \ if (CURRENT_MODEL_ISSUE > 0) { \ if (RC) \ - ppc_insn_int(my_index, cpu_model(processor), OUT_MASK, IN_MASK); \ + ppc_insn_int(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK); \ else \ - ppc_insn_int_cr(my_index, cpu_model(processor), OUT_MASK, IN_MASK, 1 << 0); \ + ppc_insn_int_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, 1 << 0); \ } \ } 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); \ + 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); \ + 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); \ + 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); \ + 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); \ + 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); \ + 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); \ + 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); \ + 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); \ + 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); \ + ppc_insn_mtcr(MY_INDEX, cpu_model(processor), INT_MASK, FXM); \ } while (0) ::model-data::: @@ -187,7 +155,7 @@ 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 */ @@ -783,6 +751,15 @@ void::model-function::model_halt:model_data *model_ptr 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; @@ -828,7 +805,7 @@ model_print *::model-function::model_mon_info:model_data *model_ptr tail = tail->next; tail->count = model_ptr->nr_stalls_writeback; tail->name = ""; - tail->suffix_plural = "times a writeback slot was unavilable"; + tail->suffix_plural = "times a write-back slot was unavailable"; tail->suffix_singular = "time a writeback was unavilable"; } @@ -942,7 +919,6 @@ void::model-function::model_branch_predict:model_data *model_ptr, int success ::internal::illegal program_interrupt(processor, cia, illegal_instruction_program_interrupt); - return 0; # The following (floating point unavailable) instruction is `known' by gen @@ -950,7 +926,6 @@ void::model-function::model_branch_predict:model_data *model_ptr, int success # executed but floating point is make unavailable by the MSR ::internal::floating_point_unavailable floating_point_unavailable_interrupt(processor, cia); - return 0; # @@ -1134,59 +1109,64 @@ void::function::convert_to_integer:cpu *processor, unsigned_word cia, unsigned64 int rbit = 0; int xbit = 0; int sign = EXTRACTED64(frb, 0, 0); - if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 63) == 0) - goto Infinity_Operand; - if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 0) - goto SNaN_Operand; - if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 1) - goto QNaN_Operand; - if (EXTRACTED64(frb, 1, 11) > 1086) goto Large_Operand; - if (EXTRACTED64(frb, 1, 11) > 0) exp = EXTRACTED64(frb, 1, 11) - 1023; - if (EXTRACTED64(frb, 1, 11) == 0) exp = -1022; - if (EXTRACTED64(frb, 1, 11) > 0) { /* normal */ - frac = BIT64(1) | INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53); - frac64 = 0; - } - if (EXTRACTED64(frb, 1, 11) == 0) { /* denorm */ - frac = INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53); - frac64 = 0; - } - gbit = 0, rbit = 0, xbit = 0; - for (i = 1; i <= 63 - exp; i++) { - xbit = rbit | xbit; - rbit = gbit; - gbit = frac64; - frac64 = EXTRACTED64(frac, 63, 63); - frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63); - } - Round_Integer(processor, sign, &frac, &frac64, gbit, rbit, xbit, round_mode); - if (sign == 1) { /* frac[0:64] = ~frac[0:64] + 1 */ - frac = ~frac; - frac64 ^= 1; - frac += (frac64 ? 1 : 0); - frac64 = (frac64 + 1) & 0x1; - } - if (tgt_precision == 32 /* can ignore frac64 in compare */ - && (signed64)frac > (signed64)MASK64(33+1, 63)/*2^31-1 >>1*/) - goto Large_Operand; - if (tgt_precision == 64 /* can ignore frac64 in compare */ - && (signed64)frac > (signed64)MASK64(1+1, 63)/*2^63-1 >>1*/) - goto Large_Operand; - if (tgt_precision == 32 /* can ignore frac64 in compare */ - && (signed64)frac < (signed64)MASK64(0, 32+1)/*-2^31 >>1*/) - goto Large_Operand; - if (tgt_precision == 64 /* can ignore frac64 in compare */ - && (signed64)frac < (signed64)MASK64(0, 0+1)/*-2^63 >>1*/) - goto Large_Operand; - FPSCR_SET_XX(FPSCR & fpscr_fi); - if (tgt_precision == 32) - *frt = MASKED64(*frt, 0, 31) | (EXTRACTED64(frac, 33, 63) << 1) | frac64; - if (tgt_precision == 64) - *frt = (EXTRACTED64(frac, 1, 63) << 1) | frac64; - /*FPSCR[fprf] = undefined */ - goto Done; - /**/ - Infinity_Operand: + enum { start, finish, Infinity_Operand, SNaN_Operand, QNaN_Operand, Large_Operand, Done } label = start; + while (label != finish) switch (label) { + case finish: + error("Unhandled switch\n"); + case start: + if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 63) == 0) + { label = Infinity_Operand; break; } + if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 0) + { label = SNaN_Operand; break; } + if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 1) + { label = QNaN_Operand; break; } + if (EXTRACTED64(frb, 1, 11) > 1086) { label = Large_Operand; break; } + if (EXTRACTED64(frb, 1, 11) > 0) exp = EXTRACTED64(frb, 1, 11) - 1023; + if (EXTRACTED64(frb, 1, 11) == 0) exp = -1022; + if (EXTRACTED64(frb, 1, 11) > 0) { /* normal */ + frac = BIT64(1) | INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53); + frac64 = 0; + } + if (EXTRACTED64(frb, 1, 11) == 0) { /* denorm */ + frac = INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53); + frac64 = 0; + } + gbit = 0, rbit = 0, xbit = 0; + for (i = 1; i <= 63 - exp; i++) { + xbit = rbit | xbit; + rbit = gbit; + gbit = frac64; + frac64 = EXTRACTED64(frac, 63, 63); + frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63); + } + Round_Integer(processor, sign, &frac, &frac64, gbit, rbit, xbit, round_mode); + if (sign == 1) { /* frac[0:64] = ~frac[0:64] + 1 */ + frac = ~frac; + frac64 ^= 1; + frac += (frac64 ? 1 : 0); + frac64 = (frac64 + 1) & 0x1; + } + if (tgt_precision == 32 /* can ignore frac64 in compare */ + && (signed64)frac > (signed64)MASK64(33+1, 63)/*2^31-1 >>1*/) + { label = Large_Operand; break; } + if (tgt_precision == 64 /* can ignore frac64 in compare */ + && (signed64)frac > (signed64)MASK64(1+1, 63)/*2^63-1 >>1*/) + { label = Large_Operand; break; } + if (tgt_precision == 32 /* can ignore frac64 in compare */ + && (signed64)frac < (signed64)MASK64(0, 32+1)/*-2^31 >>1*/) + { label = Large_Operand; break; } + if (tgt_precision == 64 /* can ignore frac64 in compare */ + && (signed64)frac < (signed64)MASK64(0, 0+1)/*-2^63 >>1*/) + { label = Large_Operand; break; } + FPSCR_SET_XX(FPSCR & fpscr_fi); + if (tgt_precision == 32) + *frt = MASKED64(*frt, 0, 31) | (EXTRACTED64(frac, 33, 63) << 1) | frac64; + if (tgt_precision == 64) + *frt = (EXTRACTED64(frac, 1, 63) << 1) | frac64; + /*FPSCR[fprf] = undefined */ + { label = Done; break; } + /**/ + case Infinity_Operand: FPSCR_SET_FR(0); FPSCR_SET_FI(0); FPSCR_OR_VX(fpscr_vxcvi); @@ -1201,9 +1181,9 @@ void::function::convert_to_integer:cpu *processor, unsigned_word cia, unsigned64 } /* FPSCR[FPRF] = undefined */ } - goto Done; + { label = Done; break; } /**/ - SNaN_Operand: + case SNaN_Operand: FPSCR_SET_FR(0); FPSCR_SET_FI(0); FPSCR_OR_VX(fpscr_vxsnan | fpscr_vxcvi); @@ -1212,9 +1192,9 @@ void::function::convert_to_integer:cpu *processor, unsigned_word cia, unsigned64 if (tgt_precision == 64) *frt = BIT64(0); /*0x8000_0000_0000_0000*/ /* FPSCR[fprf] = undefined */ } - goto Done; + { label = Done; break; } /**/ - QNaN_Operand: + case QNaN_Operand: FPSCR_SET_FR(0); FPSCR_SET_FI(0); FPSCR_OR_VX(fpscr_vxcvi); @@ -1223,9 +1203,9 @@ void::function::convert_to_integer:cpu *processor, unsigned_word cia, unsigned64 if (tgt_precision == 64) *frt = BIT64(0);/*0x8000_0000_0000_0000*/ /* FPSCR[fprf] = undefined */ } - goto Done; + { label = Done; break; } /**/ - Large_Operand: + case Large_Operand: FPSCR_SET_FR(0); FPSCR_SET_FI(0); FPSCR_OR_VX(fpscr_vxcvi); @@ -1241,7 +1221,9 @@ void::function::convert_to_integer:cpu *processor, unsigned_word cia, unsigned64 /* FPSCR[fprf] = undefined */ } /**/ - Done: + case Done: + { label = finish; break; } + } # extract out raw fields of a FP number @@ -1419,7 +1401,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, # # I.2.4.1 Branch Instructions # -0.18,6.LI,30.AA,31.LK:I:t::Branch +0.18,6.LI,30.AA,31.LK:I:::Branch *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 @@ -1430,7 +1412,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, if (CURRENT_MODEL_ISSUE > 0) model_branches(cpu_model(processor), 1, -1); -0.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:t::Branch Conditional +0.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:::Branch Conditional *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 @@ -1464,7 +1446,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, model_branch_predict(cpu_model(processor), reverse ? !succeed : succeed); } -0.19,6.BO,11.BI,16./,21.16,31.LK:XL:t::Branch Conditional to Link Register +0.19,6.BO,11.BI,16./,21.16,31.LK:XL:::Branch Conditional to Link Register *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 @@ -1490,7 +1472,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed); } -0.19,6.BO,11.BI,16./,21.528,31.LK:XL:t::Branch Conditional to Count Register +0.19,6.BO,11.BI,16./,21.528,31.LK:XL:::Branch Conditional to Count Register *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 @@ -1515,13 +1497,13 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, # # I.2.4.2 System Call Instruction # -0.17,6./,11./,16./,30.1,31./:SC:t::System Call +0.17,6./,11./,16./,30.1,31./:SC:::System Call *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 if (CURRENT_MODEL_ISSUE > 0) - model_serialize(my_index, cpu_model(processor)); + model_serialize(MY_INDEX, cpu_model(processor)); system_call_interrupt(processor, cia); # @@ -2143,22 +2125,22 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, # I.3.3.5 Fixed-Point Load and Store Multiple Instrctions # -0.46,6.RT,11.RA,16.D:D:be::Load Multiple Word +0.46,6.RT,11.RA,16.D:D:::Load Multiple Word -0.47,6.RS,11.RA,16.D:D:be::Store Multiple Word +0.47,6.RS,11.RA,16.D:D:::Store Multiple Word # # I.3.3.6 Fixed-Point Move Assist Instructions # -0.31,6.RT,11.RA,16.NB,21.597,31./:X:be::Load String Word Immediate +0.31,6.RT,11.RA,16.NB,21.597,31./:X:::Load String Word Immediate -0.31,6.RT,11.RA,16.RB,21.533,31./:X:be::Load String Word Indexed +0.31,6.RT,11.RA,16.RB,21.533,31./:X:::Load String Word Indexed -0.31,6.RS,11.RA,16.NB,21.725,31./:X:be::Store String Word Immedate +0.31,6.RS,11.RA,16.NB,21.725,31./:X:::Store String Word Immedate -0.31,6.RS,11.RA,16.RB,21.661,31./:X:be::Store String Word Indexed +0.31,6.RS,11.RA,16.RB,21.661,31./:X:::Store String Word Indexed # @@ -2259,7 +2241,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, # I.3.3.9 Fixed-Point Arithmetic Instructions # -0.14,6.RT,11.RA,16.SI:D:T::Add Immediate +0.14,6.RT,11.RA,16.SI:D:::Add Immediate *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0 @@ -4028,28 +4010,32 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, int sign; int exp; unsigned64 frac_grx; - /* split off cases for what to do */ - if (EXTRACTED64(*frB, 1, 11) < 897 - && EXTRACTED64(*frB, 1, 63) > 0) { - if ((FPSCR & fpscr_ue) == 0) goto Disabled_Exponent_Underflow; - if ((FPSCR & fpscr_ue) != 0) goto Enabled_Exponent_Underflow; - } - if (EXTRACTED64(*frB, 1, 11) > 1150 - && EXTRACTED64(*frB, 1, 11) < 2047) { - if ((FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow; - if ((FPSCR & fpscr_oe) != 0) goto Enabled_Exponent_Overflow; - } - if (EXTRACTED64(*frB, 1, 11) > 896 - && EXTRACTED64(*frB, 1, 11) < 1151) goto Normal_Operand; - if (EXTRACTED64(*frB, 1, 63) == 0) goto Zero_Operand; - if (EXTRACTED64(*frB, 1, 11) == 2047) { - if (EXTRACTED64(*frB, 12, 63) == 0) goto Infinity_Operand; - if (EXTRACTED64(*frB, 12, 12) == 1) goto QNaN_Operand; - if (EXTRACTED64(*frB, 12, 12) == 0 - && EXTRACTED64(*frB, 13, 63) > 0) goto SNaN_Operand; - } - /* handle them */ - Disabled_Exponent_Underflow: + enum { start, finish, Disabled_Exponent_Underflow, Enabled_Exponent_Underflow, Disabled_Exponent_Overflow, Enabled_Exponent_Overflow, Normal_Operand, Zero_Operand, Infinity_Operand, QNaN_Operand, SNaN_Operand, Enabled_Overflow, Done } label = start; + while (label != finish) switch (label) { + case finish: + error("Unhandled switch\n"); + case start: + /* split off cases for what to do */ + if (EXTRACTED64(*frB, 1, 11) < 897 + && EXTRACTED64(*frB, 1, 63) > 0) { + if ((FPSCR & fpscr_ue) == 0) { label = Disabled_Exponent_Underflow; break; } + if ((FPSCR & fpscr_ue) != 0) { label = Enabled_Exponent_Underflow; break; } + } + if (EXTRACTED64(*frB, 1, 11) > 1150 + && EXTRACTED64(*frB, 1, 11) < 2047) { + if ((FPSCR & fpscr_oe) == 0) { label = Disabled_Exponent_Overflow; break; } + if ((FPSCR & fpscr_oe) != 0) { label = Enabled_Exponent_Overflow; break; } + } + if (EXTRACTED64(*frB, 1, 11) > 896 + && EXTRACTED64(*frB, 1, 11) < 1151) { label = Normal_Operand; break; } + if (EXTRACTED64(*frB, 1, 63) == 0) { label = Zero_Operand; break; } + if (EXTRACTED64(*frB, 1, 11) == 2047) { + if (EXTRACTED64(*frB, 12, 63) == 0) { label = Infinity_Operand; break; } + if (EXTRACTED64(*frB, 12, 12) == 1) { label = QNaN_Operand; break; } + if (EXTRACTED64(*frB, 12, 12) == 0 + && EXTRACTED64(*frB, 13, 63) > 0) { label = SNaN_Operand; break; } + } + case Disabled_Exponent_Underflow: sign = EXTRACTED64(*frB, 0, 0); if (EXTRACTED64(*frB, 1, 11) == 0) { exp = -1022; @@ -4091,8 +4077,8 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, | INSERTED64(exp + 1023, 1, 11) | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63)); } - goto Done; - Enabled_Exponent_Underflow: + { label = Done; break; } + case Enabled_Exponent_Underflow: FPSCR_SET_UX(1); sign = EXTRACTED64(*frB, 0, 0); if (EXTRACTED64(*frB, 1, 11) == 0) { @@ -4117,8 +4103,8 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63)); if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number); if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number); - goto Done; - Disabled_Exponent_Overflow: + { label = Done; break; } + case Disabled_Exponent_Overflow: FPSCR_SET_OX(1); if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) { if (EXTRACTED64(*frB, 0, 0) == 0) { @@ -4163,43 +4149,43 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, /* FPSCR[FR] <- undefined */ FPSCR_SET_FI(1); FPSCR_SET_XX(1); - goto Done; - Enabled_Exponent_Overflow: + { label = Done; break; } + case Enabled_Exponent_Overflow: sign = EXTRACTED64(*frB, 0, 0); exp = EXTRACTED64(*frB, 1, 11) - 1023; frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52); Round_Single(processor, sign, &exp, &frac_grx); FPSCR_SET_XX(FPSCR & fpscr_fi); - Enabled_Overflow: - FPSCR_SET_OX(1); - exp = exp - 192; - *frT = (INSERTED64(sign, 0, 0) - | INSERTED64(exp + 1023, 1, 11) - | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63)); - if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number); - if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number); - goto Done; - Zero_Operand: + case Enabled_Overflow: + FPSCR_SET_OX(1); + exp = exp - 192; + *frT = (INSERTED64(sign, 0, 0) + | INSERTED64(exp + 1023, 1, 11) + | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63)); + if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number); + if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number); + { label = Done; break; } + case Zero_Operand: *frT = *frB; if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero); if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero); FPSCR_SET_FR(0); FPSCR_SET_FI(0); - goto Done; - Infinity_Operand: + { label = Done; break; } + case Infinity_Operand: *frT = *frB; if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity); if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity); FPSCR_SET_FR(0); FPSCR_SET_FI(0); - goto Done; - QNaN_Operand: + { label = Done; break; } + case QNaN_Operand: *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34); FPSCR_SET_FPRF(fpscr_rf_quiet_nan); FPSCR_SET_FR(0); FPSCR_SET_FI(0); - goto Done; - SNaN_Operand: + { label = Done; break; } + case SNaN_Operand: FPSCR_OR_VX(fpscr_vxsnan); if ((FPSCR & fpscr_ve) == 0) { *frT = (MASKED64(*frB, 0, 11) @@ -4209,23 +4195,25 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, } FPSCR_SET_FR(0); FPSCR_SET_FI(0); - goto Done; - Normal_Operand: + { label = Done; break; } + case Normal_Operand: sign = EXTRACTED64(*frB, 0, 0); exp = EXTRACTED64(*frB, 1, 11) - 1023; frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52); Round_Single(processor, sign, &exp, &frac_grx); FPSCR_SET_XX(FPSCR & fpscr_fi); - if (exp > 127 && (FPSCR & fpscr_oe) == 0) goto Disabled_Exponent_Overflow; - if (exp > 127 && (FPSCR & fpscr_oe) != 0) goto Enabled_Overflow; + if (exp > 127 && (FPSCR & fpscr_oe) == 0) { label = Disabled_Exponent_Overflow; break; } + if (exp > 127 && (FPSCR & fpscr_oe) != 0) { label = Enabled_Overflow; break; } *frT = (INSERTED64(sign, 0, 0) | INSERTED64(exp + 1023, 1, 11) | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63)); if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number); if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number); - goto Done; - Done: - PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc); + { label = Done; break; } + case Done: + PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc); + { label = finish; break; } + } 0.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword @@ -4249,30 +4237,37 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, int sign = EXTRACTED64(*frB, 0, 0); int exp = 63; unsigned64 frac = *frB; - if (frac == 0) goto Zero_Operand; - if (sign == 1) frac = ~frac + 1; - while (EXTRACTED64(frac, 0, 0) == 0) { - /*??? do the loop 0 times if (FRB) = max negative integer */ - frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62); - exp = exp - 1; - } - Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn); - if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number); - if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number); - *frT = (INSERTED64(sign, 0, 0) - | INSERTED64(exp + 1023, 1, 11) - | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63)); - goto Done; + enum { start, finish, Zero_Operand, Done } label = start; + while (label != finish) switch (label) { + case finish: + error("Unhandled switch\n"); + case start: + if (frac == 0) { label = Zero_Operand; break; } + if (sign == 1) frac = ~frac + 1; + while (EXTRACTED64(frac, 0, 0) == 0) { + /*??? do the loop 0 times if (FRB) = max negative integer */ + frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62); + exp = exp - 1; + } + Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn); + if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number); + if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number); + *frT = (INSERTED64(sign, 0, 0) + | INSERTED64(exp + 1023, 1, 11) + | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63)); + { label = Done; break; } /**/ - Zero_Operand: + case Zero_Operand: FPSCR_SET_FR(0); FPSCR_SET_FI(0); FPSCR_SET_FPRF(fpscr_rf_pos_zero); *frT = 0; - goto Done; + { label = Done; break; } /**/ - Done: - PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc); + case Done: + PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc); + { label = finish; break; } + } # # I.4.6.7 Floating-Point Compare Instructions @@ -4487,6 +4482,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, | MASKED(SRR1, 48, 63)); NIA = MASKED(SRR0, 0, 61); cpu_synchronize_context(processor); + check_masked_interrupts(processor); } # @@ -4503,8 +4499,10 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, if (IS_PROBLEM_STATE(processor)) program_interrupt(processor, cia, privileged_instruction_program_interrupt); - else + else { MSR = *rS; + check_masked_interrupts(processor); + } 0.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 @@ -4514,8 +4512,10 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, if (IS_PROBLEM_STATE(processor)) program_interrupt(processor, cia, privileged_instruction_program_interrupt); - else + else { *rT = MSR; + check_masked_interrupts(processor); + } # @@ -4591,11 +4591,37 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, 0.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All 0.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry + if (IS_PROBLEM_STATE(processor)) + program_interrupt(processor, cia, + privileged_instruction_program_interrupt); + else { + int nr = 0; + cpu *proc; + while (1) { + proc = psim_cpu(cpu_system(processor), nr); + if (proc == NULL) break; + cpu_page_tlb_invalidate_entry(proc, *rB); + nr++; + } + } 0.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All + if (IS_PROBLEM_STATE(processor)) + program_interrupt(processor, cia, + privileged_instruction_program_interrupt); + else { + int nr = 0; + cpu *proc; + while (1) { + proc = psim_cpu(cpu_system(processor), nr); + if (proc == NULL) break; + cpu_page_tlb_invalidate_all(proc); + nr++; + } + } -0.31,6./,11./,16./,21.566,31./:X:::TLB Sychronize - +0.31,6./,11./,16./,21.566,31./:X:::TLB Synchronize + /* nothing happens here - always in sync */ # # III.A.1.2 External Access Instructions |