summaryrefslogtreecommitdiff
path: root/sim/ppc/ppc-instructions
diff options
context:
space:
mode:
authorMichael Meissner <gnu@the-meissners.org>1996-07-23 15:42:42 +0000
committerMichael Meissner <gnu@the-meissners.org>1996-07-23 15:42:42 +0000
commit30c87b55ec44de3a56cecf41fc7c93ed0c4005ca (patch)
tree5752ad56a8e4c990eb02b12f68d486415c79c41b /sim/ppc/ppc-instructions
parent856bcbcbbc01a252a8df2221038100e9a33f87ff (diff)
downloadbinutils-gdb-30c87b55ec44de3a56cecf41fc7c93ed0c4005ca.tar.gz
New simulator changes from Andrew
Diffstat (limited to 'sim/ppc/ppc-instructions')
-rw-r--r--sim/ppc/ppc-instructions416
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