1 1.1 christos # 2 1.1 christos # This file is part of the program psim. 3 1.1 christos # 4 1.1 christos # Copyright 1994, 1995, 1996, 1997, 2003, 2004 Andrew Cagney 5 1.1 christos # 6 1.1 christos # -- 7 1.1 christos # 8 1.1 christos # The pseudo-code that appears below, translated into C, was copied 9 1.1 christos # by Andrew Cagney of Moss Vale, Australia. 10 1.1 christos # 11 1.1 christos # This pseudo-code is copied by permission from the publication 12 1.1 christos # "The PowerPC Architecture: A Specification for A New Family of 13 1.1 christos # RISC Processors" (ISBN 1-55860-316-6) copyright 1993, 1994 by 14 1.1 christos # International Business Machines Corporation. 15 1.1 christos # 16 1.1 christos # THIS PERMISSION IS PROVIDED WITHOUT WARRANTY OF ANY KIND, EITHER 17 1.1 christos # EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES 18 1.1 christos # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 1.1 christos # 20 1.1 christos # -- 21 1.1 christos # 22 1.1 christos # This program is free software; you can redistribute it and/or modify 23 1.1 christos # it under the terms of the GNU General Public License as published by 24 1.1 christos # the Free Software Foundation; either version 3 of the License, or 25 1.1 christos # (at your option) any later version. 26 1.1 christos # 27 1.1 christos # This program is distributed in the hope that it will be useful, 28 1.1 christos # but WITHOUT ANY WARRANTY; without even the implied warranty of 29 1.1 christos # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 30 1.1 christos # GNU General Public License for more details. 31 1.1 christos # 32 1.1 christos # You should have received a copy of the GNU General Public License 33 1.1 christos # along with this program; if not, see <http://www.gnu.org/licenses/>. 34 1.1 christos # 35 1.1 christos 36 1.1 christos :cache::::RA:RA: 37 1.1 christos :cache:::signed_word *:rA:RA:(cpu_registers(processor)->gpr + RA) 38 1.1 christos :cache:::uint32_t:RA_BITMASK:RA:(1 << RA) 39 1.1 christos :compute:::int:RA_is_0:RA:(RA == 0) 40 1.1 christos :cache::::RT:RT: 41 1.1 christos :cache:::signed_word *:rT:RT:(cpu_registers(processor)->gpr + RT) 42 1.1 christos :cache:::uint32_t:RT_BITMASK:RT:(1 << RT) 43 1.1 christos :cache::::RS:RS: 44 1.1 christos :cache:::signed_word *:rS:RS:(cpu_registers(processor)->gpr + RS) 45 1.1 christos :cache:::uint32_t:RS_BITMASK:RS:(1 << RS) 46 1.1 christos :cache::::RB:RB: 47 1.1 christos :cache:::signed_word *:rB:RB:(cpu_registers(processor)->gpr + RB) 48 1.1 christos :cache:::uint32_t:RB_BITMASK:RB:(1 << RB) 49 1.1 christos :scratch::::FRA:FRA: 50 1.1 christos :cache:::uint64_t *:frA:FRA:(cpu_registers(processor)->fpr + FRA) 51 1.1 christos :cache:::uint32_t:FRA_BITMASK:FRA:(1 << FRA) 52 1.1 christos :scratch::::FRB:FRB: 53 1.1 christos :cache:::uint64_t *:frB:FRB:(cpu_registers(processor)->fpr + FRB) 54 1.1 christos :cache:::uint32_t:FRB_BITMASK:FRB:(1 << FRB) 55 1.1 christos :scratch::::FRC:FRC: 56 1.1 christos :cache:::uint64_t *:frC:FRC:(cpu_registers(processor)->fpr + FRC) 57 1.1 christos :cache:::uint32_t:FRC_BITMASK:FRC:(1 << FRC) 58 1.1 christos :scratch::::FRS:FRS: 59 1.1 christos :cache:::uint64_t *:frS:FRS:(cpu_registers(processor)->fpr + FRS) 60 1.1 christos :cache:::uint32_t:FRS_BITMASK:FRS:(1 << FRS) 61 1.1 christos :scratch::::FRT:FRT: 62 1.1 christos :cache:::uint64_t *:frT:FRT:(cpu_registers(processor)->fpr + FRT) 63 1.1 christos :cache:::uint32_t:FRT_BITMASK:FRT:(1 << FRT) 64 1.1 christos :cache:::unsigned_word:EXTS_SI:SI:((signed_word)(int16_t)instruction) 65 1.1 christos :scratch::::BI:BI: 66 1.1 christos :cache::::BIT32_BI:BI:BIT32(BI) 67 1.1 christos :cache::::BF:BF: 68 1.1 christos :cache:::uint32_t:BF_BITMASK:BF:(1 << BF) 69 1.1 christos :scratch::::BA:BA: 70 1.1 christos :cache::::BIT32_BA:BA:BIT32(BA) 71 1.1 christos :cache:::uint32_t:BA_BITMASK:BA:(1 << BA) 72 1.1 christos :scratch::::BB:BB: 73 1.1 christos :cache::::BIT32_BB:BB:BIT32(BB) 74 1.1 christos :cache:::uint32_t:BB_BITMASK:BB:(1 << BB) 75 1.1 christos :cache::::BT:BT: 76 1.1 christos :cache:::uint32_t:BT_BITMASK:BT:(1 << BT) 77 1.1 christos :cache:::unsigned_word:EXTS_BD_0b00:BD:(((signed_word)(int16_t)instruction) & ~3) 78 1.1 christos :cache:::unsigned_word:EXTS_LI_0b00:LI:((((signed_word)(int32_t)(instruction << 6)) >> 6) & ~0x3) 79 1.1 christos :cache:::unsigned_word:EXTS_D:D:((signed_word)(int16_t)(instruction)) 80 1.1 christos :cache:::unsigned_word:EXTS_DS_0b00:DS:(((signed_word)(int16_t)instruction) & ~0x3) 81 1.1 christos #:compute:::int:SPR_is_256:SPR:(SPR == 256) 82 1.1 christos 84 1.1 christos # PowerPC models 85 1.1 christos ::model:604:ppc604: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0 86 1.1 christos ::model:603e:ppc603e:PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0 87 1.1 christos ::model:603:ppc603: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0 88 1.1 christos ::model:601:ppc601: PPC_UNIT_BAD, PPC_UNIT_BAD, 1, 1, 0 89 1.1 christos 90 1.1 christos # Flags for model.h 91 1.1 christos ::model-macro::: 92 1.1 christos #define PPC_INSN_INT(OUT_MASK, IN_MASK, RC) \ 93 1.1 christos do { \ 94 1.1 christos if (CURRENT_MODEL_ISSUE > 0) { \ 95 1.1 christos if (RC) \ 96 1.1 christos ppc_insn_int_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, 1 << 0); \ 97 1.1 christos else \ 98 1.1 christos ppc_insn_int(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK); \ 99 1.1 christos } \ 100 1.1 christos } while (0) 101 1.1 christos 102 1.1 christos #define PPC_INSN_INT_CR(OUT_MASK, IN_MASK, CR_MASK) \ 103 1.1 christos do { \ 104 1.1 christos if (CURRENT_MODEL_ISSUE > 0) \ 105 1.1 christos ppc_insn_int_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK); \ 106 1.1 christos } while (0) 107 1.1 christos 108 1.1 christos #define PPC_INSN_CR(OUT_MASK, IN_MASK) \ 109 1.1 christos do { \ 110 1.1 christos if (CURRENT_MODEL_ISSUE > 0) \ 111 1.1 christos ppc_insn_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK); \ 112 1.1 christos } while (0) 113 1.1 christos 114 1.1 christos #define PPC_INSN_FLOAT(OUT_MASK, IN_MASK, RC) \ 115 1.1 christos do { \ 116 1.1 christos if (CURRENT_MODEL_ISSUE > 0) { \ 117 1.1 christos if (RC) \ 118 1.1 christos ppc_insn_float(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK); \ 119 1.1 christos else \ 120 1.1 christos ppc_insn_float_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, 1 << 0); \ 121 1.1 christos } \ 122 1.1 christos } while (0) 123 1.1 christos 124 1.1 christos #define PPC_INSN_FLOAT_CR(OUT_MASK, IN_MASK, CR_MASK) \ 125 1.1 christos do { \ 126 1.1 christos if (CURRENT_MODEL_ISSUE > 0) \ 127 1.1 christos ppc_insn_float_cr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK); \ 128 1.1 christos } while (0) 129 1.1 christos 130 1.1 christos #define PPC_INSN_INT_FLOAT(OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK) \ 131 1.1 christos do { \ 132 1.1 christos if (CURRENT_MODEL_ISSUE > 0) \ 133 1.1 christos ppc_insn_int_float(MY_INDEX, cpu_model(processor), OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK); \ 134 1.1 christos } while (0) 135 1.1 christos 136 1.1 christos #define PPC_INSN_FROM_SPR(INT_MASK, SPR) \ 137 1.1 christos do { \ 138 1.1 christos if (CURRENT_MODEL_ISSUE > 0) \ 139 1.1 christos ppc_insn_from_spr(MY_INDEX, cpu_model(processor), INT_MASK, SPR); \ 140 1.1 christos } while (0) 141 1.1 christos 142 1.1 christos #define PPC_INSN_TO_SPR(INT_MASK, SPR) \ 143 1.1 christos do { \ 144 1.1 christos if (CURRENT_MODEL_ISSUE > 0) \ 145 1.1 christos ppc_insn_to_spr(MY_INDEX, cpu_model(processor), INT_MASK, SPR); \ 146 1.1 christos } while (0) 147 1.1 christos 148 1.1 christos #define PPC_INSN_MFCR(INT_MASK) \ 149 1.1 christos do { \ 150 1.1 christos if (CURRENT_MODEL_ISSUE > 0) \ 151 1.1 christos ppc_insn_mfcr(MY_INDEX, cpu_model(processor), INT_MASK); \ 152 1.1 christos } while (0) 153 1.1 christos 154 1.1 christos #define PPC_INSN_MTCR(INT_MASK, FXM) \ 155 1.1 christos do { \ 156 1.1 christos if (CURRENT_MODEL_ISSUE > 0) \ 157 1.1 christos ppc_insn_mtcr(MY_INDEX, cpu_model(processor), INT_MASK, FXM); \ 158 1.1 christos } while (0) 159 1.1 christos 160 1.1 christos ::model-data::: 161 1.1 christos typedef enum _ppc_function_unit { 162 1.1 christos PPC_UNIT_BAD, /* unknown function unit */ 163 1.1 christos PPC_UNIT_IU, /* integer unit (601/603 style) */ 164 1.1 christos PPC_UNIT_SRU, /* system register unit (601/603 style) */ 165 1.1 christos PPC_UNIT_SCIU1, /* 1st single cycle integer unit (604 style) */ 166 1.1 christos PPC_UNIT_SCIU2, /* 2nd single cycle integer unit (604 style) */ 167 1.1 christos PPC_UNIT_MCIU, /* multiple cycle integer unit (604 style) */ 168 1.1 christos PPC_UNIT_FPU, /* floating point unit */ 169 1.1 christos PPC_UNIT_LSU, /* load/store unit */ 170 1.1 christos PPC_UNIT_BPU, /* branch unit */ 171 1.1 christos nr_ppc_function_units 172 1.1 christos } ppc_function_unit; 173 1.1 christos 174 1.1 christos /* Structure to hold timing information on a per instruction basis */ 175 1.1 christos struct _model_time { 176 1.1 christos ppc_function_unit first_unit; /* first functional unit this insn could use */ 177 1.1 christos ppc_function_unit second_unit; /* second functional unit this insn could use */ 178 1.1 christos int16_t issue; /* # cycles before function unit can process other insns */ 179 1.1 christos int16_t done; /* # cycles before insn is done */ 180 1.1 christos uint32_t flags; /* any flags that are needed */ 181 1.1 christos }; 182 1.1 christos 183 1.1 christos /* Register mappings in status masks */ 184 1.1 christos #define PPC_CR_REG 0 /* start of CR0 .. CR7 */ 185 1.1 christos #define PPC_FPSCR_REG (PPC_CR_REG + 8) /* start of fpscr register */ 186 1.1 christos 187 1.1 christos #define PPC_NO_SPR (-1) /* flag for no SPR register */ 188 1.1 christos 189 1.1 christos /* Return if 1 bit set */ 190 1.1 christos #define PPC_ONE_BIT_SET_P(x) (((x) & ((x)-1)) == 0) 191 1.1 christos 192 1.1 christos /* Structure for each functional unit that is busy */ 193 1.1 christos typedef struct _model_busy model_busy; 194 1.1 christos struct _model_busy { 195 1.1 christos model_busy *next; /* next function unit */ 196 1.1 christos ppc_function_unit unit; /* function unit name */ 197 1.1 christos uint32_t int_busy; /* int registers that are busy */ 198 1.1 christos uint32_t fp_busy; /* floating point registers that are busy */ 199 1.1 christos uint32_t cr_fpscr_busy; /* CR/FPSCR registers that are busy */ 200 1.1 christos int16_t spr_busy; /* SPR register that is busy or PPC_NO_SPR */ 201 1.1 christos uint32_t vr_busy; /* AltiVec registers that are busy */ 202 1.1 christos int16_t vscr_busy; /* AltiVec status register busy */ 203 1.1 christos int16_t issue; /* # of cycles until unit can accept another insn */ 204 1.1 christos int16_t done; /* # of cycles until insn is done */ 205 1.1 christos int16_t nr_writebacks; /* # of registers this unit writes back */ 206 1.1 christos }; 207 1.1 christos 208 1.1 christos /* Structure to hold the current state information for the simulated CPU model */ 209 1.1 christos struct _model_data { 210 1.1 christos cpu *processor; /* point back to processor */ 211 1.1 christos const char *name; /* model name */ 212 1.1 christos const model_time *timing; /* timing information */ 213 1.1 christos model_busy busy_head; /* dummy entry to head list of busy function units */ 214 1.1 christos model_busy *busy_tail; /* tail of list of busy function units */ 215 1.1 christos model_busy *free_list; /* list of model_busy structs not in use */ 216 1.1 christos count_type nr_cycles; /* # cycles */ 217 1.1 christos count_type nr_branches; /* # branches */ 218 1.1 christos count_type nr_branches_fallthrough; /* # conditional branches that fell through */ 219 1.1 christos count_type nr_branch_predict_trues; /* # branches predicted correctly */ 220 1.1 christos count_type nr_branch_predict_falses; /* # branches predicted incorrectly */ 221 1.1 christos count_type nr_branch_conditional[32]; /* # of each type of bc */ 222 1.1 christos count_type nr_mtcrf_crs[9]; /* # of CR's moved in a mtcrf instruction */ 223 1.1 christos count_type nr_stalls_data; /* # of stalls for data */ 224 1.1 christos count_type nr_stalls_unit; /* # of stalls waiting for a function unit */ 225 1.1 christos count_type nr_stalls_serialize; /* # of stalls waiting for things to quiet down */ 226 1.1 christos count_type nr_stalls_writeback; /* # of stalls waiting for a writeback slot */ 227 1.1 christos count_type nr_units[nr_ppc_function_units]; /* function unit counts */ 228 1.1 christos int max_nr_writebacks; /* max # of writeback slots available */ 229 1.1 christos uint32_t int_busy; /* int registers that are busy */ 230 1.1 christos uint32_t fp_busy; /* floating point registers that are busy */ 231 1.1 christos uint32_t cr_fpscr_busy; /* CR/FPSCR registers that are busy */ 232 1.1 christos uint8_t spr_busy[nr_of_sprs]; /* SPR registers that are busy */ 233 1.1 christos uint32_t vr_busy; /* AltiVec registers that are busy */ 234 1.1 christos uint8_t vscr_busy; /* AltiVec SC register busy */ 235 1.1 christos uint8_t busy[nr_ppc_function_units]; /* whether a function is busy or not */ 236 1.1 christos }; 237 1.1 christos 238 1.1 christos static const char *const ppc_function_unit_name[ (int)nr_ppc_function_units ] = { 239 1.1 christos "unknown functional unit instruction", 240 1.1 christos "integer functional unit instruction", 241 1.1 christos "system register functional unit instruction", 242 1.1 christos "1st single cycle integer functional unit instruction", 243 1.1 christos "2nd single cycle integer functional unit instruction", 244 1.1 christos "multiple cycle integer functional unit instruction", 245 1.1 christos "floating point functional unit instruction", 246 1.1 christos "load/store functional unit instruction", 247 1.1 christos "branch functional unit instruction", 248 1.1 christos }; 249 1.1 christos 250 1.1 christos static const char *const ppc_branch_conditional_name[32] = { 251 1.1 christos "branch if --CTR != 0 and condition is FALSE", /* 0000y */ 252 1.1 christos "branch if --CTR != 0 and condition is FALSE, reverse branch likely", 253 1.1 christos "branch if --CTR == 0 and condition is FALSE", /* 0001y */ 254 1.1 christos "branch if --CTR == 0 and condition is FALSE, reverse branch likely", 255 1.1 christos "branch if the condition is FALSE", /* 001zy */ 256 1.1 christos "branch if the condition is FALSE, reverse branch likely", 257 1.1 christos "branch if the condition is FALSE (ignored bit 1 set to 1)", /* 001zy */ 258 1.1 christos "branch if the condition is FALSE, reverse branch likely (ignored bit 4 set to 1)", 259 1.1 christos "branch if --CTR != 0 and condition is TRUE", /* 0100y */ 260 1.1 christos "branch if --CTR != 0 and condition is TRUE, reverse branch likely", 261 1.1 christos "branch if --CTR == 0 and condition is TRUE", /* 0101y */ 262 1.1 christos "branch if --CTR == 0 and condition is TRUE, reverse branch likely", 263 1.1 christos "branch if the condition is TRUE", /* 011zy */ 264 1.1 christos "branch if the condition is TRUE, reverse branch likely", 265 1.1 christos "branch if the condition is TRUE (ignored bit 1 set to 1)", /* 011zy */ 266 1.1 christos "branch if the condition is TRUE, reverse branch likely (ignored bit 4 set to 1)", 267 1.1 christos "branch if --CTR != 0", /* 1z00y */ 268 1.1 christos "branch if --CTR != 0, reverse branch likely", 269 1.1 christos "branch if --CTR == 0", /* 1z01y */ 270 1.1 christos "branch if --CTR == 0, reverse branch likely", 271 1.1 christos "branch always", /* 1z1zz */ 272 1.1 christos "branch always (ignored bit 5 set to 1)", 273 1.1 christos "branch always (ignored bit 4 set to 1)", /* 1z1zz */ 274 1.1 christos "branch always (ignored bits 4,5 set to 1)", 275 1.1 christos "branch if --CTR != 0 (ignored bit 1 set to 1)", /* 1z00y */ 276 1.1 christos "branch if --CTR != 0, reverse branch likely (ignored bit 1 set to 1)", 277 1.1 christos "branch if --CTR == 0 (ignored bit 1 set to 1)", /* 1z01y */ 278 1.1 christos "branch if --CTR == 0, reverse branch likely (ignored bit 1 set to 1)", 279 1.1 christos "branch always (ignored bit 1 set to 1)", /* 1z1zz */ 280 1.1 christos "branch always (ignored bits 1,5 set to 1)", 281 1.1 christos "branch always (ignored bits 1,4 set to 1)", /* 1z1zz */ 282 1.1 christos "branch always (ignored bits 1,4,5 set to 1)", 283 1.1 christos }; 284 1.1 christos 285 1.1 christos static const char *const ppc_nr_mtcrf_crs[9] = { 286 1.1 christos "mtcrf moving 0 CRs", 287 1.1 christos "mtcrf moving 1 CR", 288 1.1 christos "mtcrf moving 2 CRs", 289 1.1 christos "mtcrf moving 3 CRs", 290 1.1 christos "mtcrf moving 4 CRs", 291 1.1 christos "mtcrf moving 5 CRs", 292 1.1 christos "mtcrf moving 6 CRs", 293 1.1 christos "mtcrf moving 7 CRs", 294 1.1 christos "mtcrf moving all CRs", 295 1.1 christos }; 296 1.1 christos 298 1.1 christos # Trace releasing resources 299 1.1 christos void::model-static::model_trace_release:model_data *model_ptr, model_busy *busy 300 1.1 christos int i; 301 1.1 christos TRACE(trace_model,("done, %s, %d writeback%s\n", ppc_function_unit_name[busy->unit], 302 1.1 christos busy->nr_writebacks, busy->nr_writebacks == 1 ? "" : "s")); 303 1.1 christos if (busy->int_busy) { 304 1.1 christos for(i = 0; i < 32; i++) { 305 1.1 christos if (((1 << i) & busy->int_busy) != 0) { 306 1.1 christos TRACE(trace_model, ("Register r%d is now available.\n", i)); 307 1.1 christos } 308 1.1 christos } 309 1.1 christos } 310 1.1 christos if (busy->fp_busy) { 311 1.1 christos for(i = 0; i < 32; i++) { 312 1.1 christos if (((1 << i) & busy->fp_busy) != 0) { 313 1.1 christos TRACE(trace_model, ("Register f%d is now available.\n", i)); 314 1.1 christos } 315 1.1 christos } 316 1.1 christos } 317 1.1 christos if (busy->cr_fpscr_busy) { 318 1.1 christos for(i = 0; i < 8; i++) { 319 1.1 christos if (((1 << i) & busy->cr_fpscr_busy) != 0) { 320 1.1 christos TRACE(trace_model, ("Register cr%d is now available.\n", i)); 321 1.1 christos } 322 1.1 christos } 323 1.1 christos if (busy->cr_fpscr_busy & 0x100) 324 1.1 christos TRACE(trace_model, ("Register fpscr is now available.\n")); 325 1.1 christos } 326 1.1 christos if (busy->spr_busy != PPC_NO_SPR) 327 1.1 christos TRACE(trace_model, ("Register %s is now available.\n", spr_name(busy->spr_busy))); 328 1.1 christos if (busy->vr_busy) { 329 1.1 christos for(i = 0; i < 32; i++) { 330 1.1 christos if (((1 << i) & busy->vr_busy) != 0) { 331 1.1 christos TRACE(trace_model, ("Register v%d is now available.\n", i)); 332 1.1 christos } 333 1.1 christos } 334 1.1 christos } 335 1.1 christos if (busy->vscr_busy) 336 1.1 christos TRACE(trace_model, ("VSCR Register %s is now available.\n", spr_name(busy->spr_busy))); 337 1.1 christos 338 1.1 christos # Trace making registers busy 339 1.1 christos void::model-static::model_trace_make_busy:model_data *model_ptr, uint32_t int_mask, uint32_t fp_mask, uint32_t cr_mask 340 1.1 christos int i; 341 1.1 christos if (int_mask) { 342 1.1 christos for(i = 0; i < 32; i++) { 343 1.1 christos if (((1 << i) & int_mask) != 0) { 344 1.1 christos TRACE(trace_model, ("Register r%d is now busy.\n", i)); 345 1.1 christos } 346 1.1 christos } 347 1.1 christos } 348 1.1 christos if (fp_mask) { 349 1.1 christos for(i = 0; i < 32; i++) { 350 1.1 christos if (((1 << i) & fp_mask) != 0) { 351 1.1 christos TRACE(trace_model, ("Register f%d is now busy.\n", i)); 352 1.1 christos } 353 1.1 christos } 354 1.1 christos } 355 1.1 christos if (cr_mask) { 356 1.1 christos for(i = 0; i < 8; i++) { 357 1.1 christos if (((1 << i) & cr_mask) != 0) { 358 1.1 christos TRACE(trace_model, ("Register cr%d is now busy.\n", i)); 359 1.1 christos } 360 1.1 christos } 361 1.1 christos } 362 1.1 christos 363 1.1 christos # Trace waiting for registers to become available 364 1.1 christos void::model-static::model_trace_busy_p:model_data *model_ptr, uint32_t int_busy, uint32_t fp_busy, uint32_t cr_or_fpscr_busy, int spr_busy 365 1.1 christos int i; 366 1.1 christos if (int_busy) { 367 1.1 christos int_busy &= model_ptr->int_busy; 368 1.1 christos for(i = 0; i < 32; i++) { 369 1.1 christos if (((1 << i) & int_busy) != 0) { 370 1.1 christos TRACE(trace_model, ("Waiting for register r%d.\n", i)); 371 1.1 christos } 372 1.1 christos } 373 1.1 christos } 374 1.1 christos if (fp_busy) { 375 1.1 christos fp_busy &= model_ptr->fp_busy; 376 1.1 christos for(i = 0; i < 32; i++) { 377 1.1 christos if (((1 << i) & fp_busy) != 0) { 378 1.1 christos TRACE(trace_model, ("Waiting for register f%d.\n", i)); 379 1.1 christos } 380 1.1 christos } 381 1.1 christos } 382 1.1 christos if (cr_or_fpscr_busy) { 383 1.1 christos cr_or_fpscr_busy &= model_ptr->cr_fpscr_busy; 384 1.1 christos for(i = 0; i < 8; i++) { 385 1.1 christos if (((1 << i) & cr_or_fpscr_busy) != 0) { 386 1.1 christos TRACE(trace_model, ("Waiting for register cr%d.\n", i)); 387 1.1 christos } 388 1.1 christos } 389 1.1 christos if (cr_or_fpscr_busy & 0x100) 390 1.1 christos TRACE(trace_model, ("Waiting for register fpscr.\n")); 391 1.1 christos } 392 1.1 christos if (spr_busy != PPC_NO_SPR && model_ptr->spr_busy[spr_busy]) 393 1.1 christos TRACE(trace_model, ("Waiting for register %s.\n", spr_name(spr_busy))); 394 1.1 christos 396 1.1 christos # Advance state to next cycle, releasing any registers allocated 397 1.1 christos void::model-internal::model_new_cycle:model_data *model_ptr 398 1.1 christos model_busy *cur_busy = model_ptr->busy_head.next; 399 1.1 christos model_busy *free_list = model_ptr->free_list; 400 1.1 christos model_busy *busy_tail = &model_ptr->busy_head; 401 1.1 christos int nr_writebacks = model_ptr->max_nr_writebacks; 402 1.1 christos model_busy *next; 403 1.1 christos 404 1.1 christos model_ptr->nr_cycles++; 405 1.1 christos TRACE(trace_model,("New cycle %lu\n", (unsigned long)model_ptr->nr_cycles)); 406 1.1 christos for ( ; cur_busy; cur_busy = next) { 407 1.1 christos next = cur_busy->next; 408 1.1 christos if (--cur_busy->done <= 0) { /* function unit done, release registers if we have writeback slots */ 409 1.1 christos nr_writebacks -= cur_busy->nr_writebacks; 410 1.1 christos if (nr_writebacks >= 0) { 411 1.1 christos model_ptr->int_busy &= ~cur_busy->int_busy; 412 1.1 christos model_ptr->fp_busy &= ~cur_busy->fp_busy; 413 1.1 christos model_ptr->cr_fpscr_busy &= ~cur_busy->cr_fpscr_busy; 414 1.1 christos if (cur_busy->spr_busy != PPC_NO_SPR) 415 1.1 christos model_ptr->spr_busy[cur_busy->spr_busy] = 0; 416 1.1 christos model_ptr->vr_busy &= ~cur_busy->vr_busy; 417 1.1 christos model_ptr->vscr_busy = ~cur_busy->vscr_busy; 418 1.1 christos 419 1.1 christos if (WITH_TRACE && ppc_trace[trace_model]) 420 1.1 christos model_trace_release(model_ptr, cur_busy); 421 1.1 christos 422 1.1 christos model_ptr->busy[cur_busy->unit] = 0; 423 1.1 christos cur_busy->next = free_list; 424 1.1 christos free_list = cur_busy; 425 1.1 christos } 426 1.1 christos else { /* writeback slots not available */ 427 1.1 christos TRACE(trace_model,("%d writeback slot%s not available for %s\n", 428 1.1 christos cur_busy->nr_writebacks, 429 1.1 christos cur_busy->nr_writebacks == 1 ? " is" : "s are", 430 1.1 christos ppc_function_unit_name[cur_busy->unit])); 431 1.1 christos cur_busy->done++; /* undo -- above */ 432 1.1 christos model_ptr->nr_stalls_writeback++; 433 1.1 christos busy_tail->next = cur_busy; 434 1.1 christos busy_tail = cur_busy; 435 1.1 christos } 436 1.1 christos } 437 1.1 christos else if (--cur_busy->issue <= 0) { /* function unit pipelined, allow new use */ 438 1.1 christos TRACE(trace_model,("pipeline, %s ready for next client\n", ppc_function_unit_name[cur_busy->unit])); 439 1.1 christos model_ptr->busy[cur_busy->unit] = 0; 440 1.1 christos busy_tail->next = cur_busy; 441 1.1 christos busy_tail = cur_busy; 442 1.1 christos } 443 1.1 christos else { 444 1.1 christos TRACE(trace_model,("%s still working, issue = %d, done = %d\n", 445 1.1 christos ppc_function_unit_name[cur_busy->unit], 446 1.1 christos cur_busy->issue, 447 1.1 christos cur_busy->done)); 448 1.1 christos busy_tail->next = cur_busy; 449 1.1 christos busy_tail = cur_busy; 450 1.1 christos } 451 1.1 christos } 452 1.1 christos 453 1.1 christos busy_tail->next = (model_busy *)0; 454 1.1 christos model_ptr->busy_tail = busy_tail; 455 1.1 christos model_ptr->free_list = free_list; 456 1.1 christos 457 1.1 christos # Mark a function unit as busy, return the busy structure 458 1.1 christos model_busy *::model-internal::model_make_busy:model_data *model_ptr, ppc_function_unit unit, int issue, int done 459 1.1 christos model_busy *busy; 460 1.1 christos 461 1.1 christos TRACE(trace_model,("unit = %s, issue = %d, done = %d\n", ppc_function_unit_name[unit], issue, done)); 462 1.1 christos 463 1.1 christos if (!model_ptr->free_list) { 464 1.1 christos busy = ZALLOC(model_busy); 465 1.1 christos } 466 1.1 christos else { 467 1.1 christos busy = model_ptr->free_list; 468 1.1 christos model_ptr->free_list = busy->next; 469 1.1 christos busy->next = (model_busy *)0; 470 1.1 christos busy->int_busy = 0; 471 1.1 christos busy->fp_busy = 0; 472 1.1 christos busy->cr_fpscr_busy = 0; 473 1.1 christos busy->nr_writebacks = 0; 474 1.1 christos busy->vr_busy = 0; 475 1.1 christos busy->vscr_busy = 0; 476 1.1 christos } 477 1.1 christos 478 1.1 christos busy->unit = unit; 479 1.1 christos busy->issue = issue; 480 1.1 christos busy->done = done; 481 1.1 christos busy->spr_busy = PPC_NO_SPR; 482 1.1 christos model_ptr->busy_tail->next = busy; 483 1.1 christos model_ptr->busy_tail = busy; 484 1.1 christos model_ptr->busy[unit] = 1; 485 1.1 christos model_ptr->nr_units[unit]++; 486 1.1 christos return busy; 487 1.1 christos 489 1.1 christos # Wait until a function unit is non-busy, and then allocate a busy pointer & return the pointer 490 1.1 christos model_busy *::model-internal::model_wait_for_unit:itable_index index, model_data *const model_ptr, const model_time *const time_ptr 491 1.1 christos ppc_function_unit first_unit = time_ptr->first_unit; 492 1.1 christos ppc_function_unit second_unit = time_ptr->second_unit; 493 1.1 christos int stall_increment = 0; 494 1.1 christos 495 1.1 christos for (;;) { 496 1.1 christos if (!model_ptr->busy[first_unit]) 497 1.1 christos return model_make_busy(model_ptr, first_unit, 498 1.1 christos model_ptr->timing[index].issue, 499 1.1 christos model_ptr->timing[index].done); 500 1.1 christos 501 1.1 christos if (!model_ptr->busy[second_unit]) 502 1.1 christos return model_make_busy(model_ptr, second_unit, 503 1.1 christos model_ptr->timing[index].issue, 504 1.1 christos model_ptr->timing[index].done); 505 1.1 christos 506 1.1 christos TRACE(trace_model,("all function units are busy for %s\n", itable[index].name)); 507 1.1 christos model_ptr->nr_stalls_unit += stall_increment; /* don't count first stall */ 508 1.1 christos stall_increment = 1; 509 1.1 christos model_new_cycle(model_ptr); 510 1.1 christos } 511 1.1 christos 512 1.1 christos # Serialize the processor, waiting for all instructions to drain out before adding an instruction. 513 1.1 christos void::model-function::model_serialize:itable_index index, model_data *model_ptr 514 1.1 christos while (model_ptr->busy_head.next) { 515 1.1 christos TRACE(trace_model,("waiting for pipeline to empty\n")); 516 1.1 christos model_ptr->nr_stalls_serialize++; 517 1.1 christos model_new_cycle(model_ptr); 518 1.1 christos } 519 1.1 christos (void) model_make_busy(model_ptr, 520 1.1 christos model_ptr->timing[index].first_unit, 521 1.1 christos model_ptr->timing[index].issue, 522 1.1 christos model_ptr->timing[index].done); 523 1.1 christos 524 1.1 christos # Wait for a CR to become unbusy 525 1.1 christos void::model-function::model_wait_for_cr:model_data *model_ptr, unsigned CRBIT 526 1.1 christos unsigned u; 527 1.1 christos uint32_t cr_mask; 528 1.1 christos int cr_var = 0; 529 1.1 christos for (u = 0xc0000000; (u != 0) && (CRBIT & u) == 0; u >>= 4 ) 530 1.1 christos cr_var++; 531 1.1 christos 532 1.1 christos cr_mask = (1 << cr_var); 533 1.1 christos while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) { 534 1.1 christos TRACE(trace_model,("waiting for CR %d\n", cr_var)); 535 1.1 christos model_ptr->nr_stalls_data++; 536 1.1 christos model_new_cycle(model_ptr); 537 1.1 christos } 538 1.1 christos 539 1.1 christos # Schedule an instruction that takes integer input registers and produces output registers 540 1.1 christos void::model-function::ppc_insn_int:itable_index index, model_data *model_ptr, const uint32_t out_mask, const uint32_t in_mask 541 1.1 christos const uint32_t int_mask = out_mask | in_mask; 542 1.1 christos model_busy *busy_ptr; 543 1.1 christos 544 1.1 christos if ((model_ptr->int_busy & int_mask) != 0) { 545 1.1 christos model_new_cycle(model_ptr); /* don't count first dependency as a stall */ 546 1.1 christos 547 1.1 christos while ((model_ptr->int_busy & int_mask) != 0) { 548 1.1 christos if (WITH_TRACE && ppc_trace[trace_model]) 549 1.1 christos model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR); 550 1.1 christos 551 1.1 christos model_ptr->nr_stalls_data++; 552 1.1 christos model_new_cycle(model_ptr); 553 1.1 christos } 554 1.1 christos } 555 1.1 christos 556 1.1 christos busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]); 557 1.1 christos model_ptr->int_busy |= out_mask; 558 1.1 christos busy_ptr->int_busy |= out_mask; 559 1.1 christos if (out_mask) 560 1.1 christos busy_ptr->nr_writebacks = (PPC_ONE_BIT_SET_P(out_mask)) ? 1 : 2; 561 1.1 christos 562 1.1 christos if (WITH_TRACE && ppc_trace[trace_model]) 563 1.1 christos model_trace_make_busy(model_ptr, out_mask, 0, 0); 564 1.1 christos 565 1.1 christos # Schedule an instruction that takes integer input registers and produces output registers & sets a CR register 566 1.1 christos void::model-function::ppc_insn_int_cr:itable_index index, model_data *model_ptr, const uint32_t out_mask, const uint32_t in_mask, const uint32_t cr_mask 567 1.1 christos const uint32_t int_mask = out_mask | in_mask; 568 1.1 christos model_busy *busy_ptr; 569 1.1 christos 570 1.1 christos if ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) { 571 1.1 christos model_new_cycle(model_ptr); /* don't count first dependency as a stall */ 572 1.1 christos 573 1.1 christos while ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) { 574 1.1 christos if (WITH_TRACE && ppc_trace[trace_model]) 575 1.1 christos model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR); 576 1.1 christos 577 1.1 christos model_ptr->nr_stalls_data++; 578 1.1 christos model_new_cycle(model_ptr); 579 1.1 christos } 580 1.1 christos } 581 1.1 christos 582 1.1 christos busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]); 583 1.1 christos model_ptr->int_busy |= out_mask; 584 1.1 christos busy_ptr->int_busy |= out_mask; 585 1.1 christos model_ptr->cr_fpscr_busy |= cr_mask; 586 1.1 christos busy_ptr->cr_fpscr_busy |= cr_mask; 587 1.1 christos if (out_mask) 588 1.1 christos busy_ptr->nr_writebacks = (PPC_ONE_BIT_SET_P(out_mask)) ? 1 : 2; 589 1.1 christos 590 1.1 christos if (cr_mask) 591 1.1 christos busy_ptr->nr_writebacks++; 592 1.1 christos 593 1.1 christos if (WITH_TRACE && ppc_trace[trace_model]) 594 1.1 christos model_trace_make_busy(model_ptr, out_mask, 0, cr_mask); 595 1.1 christos 596 1.1 christos 597 1.1 christos # Schedule an instruction that takes CR input registers and produces output CR registers 598 1.1 christos void::model-function::ppc_insn_cr:itable_index index, model_data *model_ptr, const uint32_t out_mask, const uint32_t in_mask 599 1.1 christos const uint32_t cr_mask = out_mask | in_mask; 600 1.1 christos model_busy *busy_ptr; 601 1.1 christos 602 1.1 christos if ((model_ptr->cr_fpscr_busy & cr_mask) != 0) { 603 1.1 christos model_new_cycle(model_ptr); /* don't count first dependency as a stall */ 604 1.1 christos 605 1.1 christos while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) { 606 1.1 christos if (WITH_TRACE && ppc_trace[trace_model]) 607 1.1 christos model_trace_busy_p(model_ptr, 0, 0, cr_mask, PPC_NO_SPR); 608 1.1 christos 609 1.1 christos model_ptr->nr_stalls_data++; 610 1.1 christos model_new_cycle(model_ptr); 611 1.1 christos } 612 1.1 christos } 613 1.1 christos 614 1.1 christos busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]); 615 1.1 christos model_ptr->cr_fpscr_busy |= out_mask; 616 1.1 christos busy_ptr->cr_fpscr_busy |= out_mask; 617 1.1 christos if (out_mask) 618 1.1 christos busy_ptr->nr_writebacks = 1; 619 1.1 christos 620 1.1 christos if (WITH_TRACE && ppc_trace[trace_model]) 621 1.1 christos model_trace_make_busy(model_ptr, 0, 0, out_mask); 622 1.1 christos 623 1.1 christos 624 1.1 christos # Schedule an instruction that takes floating point input registers and produces an output fp register 625 1.1 christos void::model-function::ppc_insn_float:itable_index index, model_data *model_ptr, const uint32_t out_mask, const uint32_t in_mask 626 1.1 christos const uint32_t fp_mask = out_mask | in_mask; 627 1.1 christos model_busy *busy_ptr; 628 1.1 christos 629 1.1 christos if ((model_ptr->fp_busy & fp_mask) != 0) { 630 1.1 christos model_new_cycle(model_ptr); /* don't count first dependency as a stall */ 631 1.1 christos 632 1.1 christos while ((model_ptr->fp_busy & fp_mask) != 0) { 633 1.1 christos if (WITH_TRACE && ppc_trace[trace_model]) 634 1.1 christos model_trace_busy_p(model_ptr, 0, fp_mask, 0, PPC_NO_SPR); 635 1.1 christos 636 1.1 christos model_ptr->nr_stalls_data++; 637 1.1 christos model_new_cycle(model_ptr); 638 1.1 christos } 639 1.1 christos } 640 1.1 christos 641 1.1 christos busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]); 642 1.1 christos model_ptr->fp_busy |= out_mask; 643 1.1 christos busy_ptr->fp_busy |= out_mask; 644 1.1 christos busy_ptr->nr_writebacks = 1; 645 1.1 christos if (WITH_TRACE && ppc_trace[trace_model]) 646 1.1 christos model_trace_make_busy(model_ptr, 0, out_mask, 0); 647 1.1 christos 648 1.1 christos 649 1.1 christos # Schedule an instruction that takes floating point input registers and produces an output fp register & sets a CR reg 650 1.1 christos void::model-function::ppc_insn_float_cr:itable_index index, model_data *model_ptr, const uint32_t out_mask, const uint32_t in_mask, const uint32_t cr_mask 651 1.1 christos const uint32_t fp_mask = out_mask | in_mask; 652 1.1 christos model_busy *busy_ptr; 653 1.1 christos 654 1.1 christos if ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) { 655 1.1 christos model_new_cycle(model_ptr); /* don't count first dependency as a stall */ 656 1.1 christos 657 1.1 christos while ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) { 658 1.1 christos if (WITH_TRACE && ppc_trace[trace_model]) 659 1.1 christos model_trace_busy_p(model_ptr, 0, fp_mask, cr_mask, PPC_NO_SPR); 660 1.1 christos 661 1.1 christos model_ptr->nr_stalls_data++; 662 1.1 christos model_new_cycle(model_ptr); 663 1.1 christos } 664 1.1 christos } 665 1.1 christos 666 1.1 christos busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]); 667 1.1 christos model_ptr->fp_busy |= out_mask; 668 1.1 christos busy_ptr->fp_busy |= out_mask; 669 1.1 christos model_ptr->cr_fpscr_busy |= cr_mask; 670 1.1 christos busy_ptr->cr_fpscr_busy |= cr_mask; 671 1.1 christos busy_ptr->nr_writebacks = (cr_mask) ? 2 : 1; 672 1.1 christos if (WITH_TRACE && ppc_trace[trace_model]) 673 1.1 christos model_trace_make_busy(model_ptr, 0, out_mask, cr_mask); 674 1.1 christos 675 1.1 christos 676 1.1 christos # Schedule an instruction that takes both int/float input registers and produces output int/float registers 677 1.1 christos void::model-function::ppc_insn_int_float:itable_index index, model_data *model_ptr, const uint32_t out_int_mask, const uint32_t out_fp_mask, const uint32_t in_int_mask, const uint32_t in_fp_mask 678 1.1 christos const uint32_t int_mask = out_int_mask | in_int_mask; 679 1.1 christos const uint32_t fp_mask = out_fp_mask | in_fp_mask; 680 1.1 christos model_busy *busy_ptr; 681 1.1 christos 682 1.1 christos if ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) { 683 1.1 christos model_new_cycle(model_ptr); /* don't count first dependency as a stall */ 684 1.1 christos 685 1.1 christos while ((model_ptr->int_busy & int_mask) || (model_ptr->fp_busy & fp_mask)) { 686 1.1 christos if (WITH_TRACE && ppc_trace[trace_model]) 687 1.1 christos model_trace_busy_p(model_ptr, int_mask, fp_mask, 0, PPC_NO_SPR); 688 1.1 christos 689 1.1 christos model_ptr->nr_stalls_data++; 690 1.1 christos model_new_cycle(model_ptr); 691 1.1 christos } 692 1.1 christos 693 1.1 christos busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]); 694 1.1 christos model_ptr->int_busy |= out_int_mask; 695 1.1 christos busy_ptr->int_busy |= out_int_mask; 696 1.1 christos model_ptr->fp_busy |= out_fp_mask; 697 1.1 christos busy_ptr->fp_busy |= out_fp_mask; 698 1.1 christos busy_ptr->nr_writebacks = ((out_int_mask) ? 1 : 0) + ((out_fp_mask) ? 1 : 0); 699 1.1 christos if (WITH_TRACE && ppc_trace[trace_model]) 700 1.1 christos model_trace_make_busy(model_ptr, out_int_mask, out_fp_mask, 0); 701 1.1 christos return; 702 1.1 christos } 703 1.1 christos 704 1.1 christos # Schedule an MFSPR instruction that takes 1 special purpose register and produces an integer output register 705 1.1 christos void::model-function::ppc_insn_from_spr:itable_index index, model_data *model_ptr, const uint32_t int_mask, const unsigned nSPR 706 1.1 christos model_busy *busy_ptr; 707 1.1 christos 708 1.1 christos while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) { 709 1.1 christos if (WITH_TRACE && ppc_trace[trace_model]) 710 1.1 christos model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR); 711 1.1 christos 712 1.1 christos model_ptr->nr_stalls_data++; 713 1.1 christos model_new_cycle(model_ptr); 714 1.1 christos } 715 1.1 christos 716 1.1 christos busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]); 717 1.1 christos model_ptr->int_busy |= int_mask; 718 1.1 christos busy_ptr->int_busy |= int_mask; 719 1.1 christos busy_ptr->nr_writebacks = 1; 720 1.1 christos if (WITH_TRACE && ppc_trace[trace_model]) 721 1.1 christos model_trace_make_busy(model_ptr, int_mask, 0, 0); 722 1.1 christos 723 1.1 christos # Schedule an MTSPR instruction that takes 1 integer register and produces a special purpose output register 724 1.1 christos void::model-function::ppc_insn_to_spr:itable_index index, model_data *model_ptr, const uint32_t int_mask, const unsigned nSPR 725 1.1 christos model_busy *busy_ptr; 726 1.1 christos 727 1.1 christos while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) { 728 1.1 christos if (WITH_TRACE && ppc_trace[trace_model]) 729 1.1 christos model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR); 730 1.1 christos 731 1.1 christos model_ptr->nr_stalls_data++; 732 1.1 christos model_new_cycle(model_ptr); 733 1.1 christos } 734 1.1 christos 735 1.1 christos busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]); 736 1.1 christos busy_ptr->spr_busy = nSPR; 737 1.1 christos model_ptr->spr_busy[nSPR] = 1; 738 1.1 christos busy_ptr->nr_writebacks = 1; 739 1.1 christos TRACE(trace_model,("Making register %s busy.\n", spr_name(nSPR))); 740 1.1 christos 741 1.1 christos # Schedule a MFCR instruction that moves the CR into an integer register 742 1.1 christos void::model-function::ppc_insn_mfcr:itable_index index, model_data *model_ptr, uint32_t int_mask 743 1.1 christos const uint32_t cr_mask = 0xff; 744 1.1 christos model_busy *busy_ptr; 745 1.1 christos 746 1.1 christos while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) { 747 1.1 christos if (WITH_TRACE && ppc_trace[trace_model]) 748 1.1 christos model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR); 749 1.1 christos 750 1.1 christos model_ptr->nr_stalls_data++; 751 1.1 christos model_new_cycle(model_ptr); 752 1.1 christos } 753 1.1 christos 754 1.1 christos busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]); 755 1.1 christos model_ptr->int_busy |= int_mask; 756 1.1 christos busy_ptr->int_busy |= int_mask; 757 1.1 christos busy_ptr->nr_writebacks = 1; 758 1.1 christos if (WITH_TRACE && ppc_trace[trace_model]) 759 1.1 christos model_trace_make_busy(model_ptr, int_mask, 0, 0); 760 1.1 christos 761 1.1 christos # Schedule a MTCR instruction that moves an integer register into the CR 762 1.1 christos void::model-function::ppc_insn_mtcr:itable_index index, model_data *model_ptr, uint32_t int_mask, unsigned FXM 763 1.1 christos int f; 764 1.1 christos int nr_crs = 0; 765 1.1 christos uint32_t cr_mask = 0; 766 1.1 christos const model_time *normal_time = &model_ptr->timing[index]; 767 1.1 christos static const model_time ppc604_1bit_time = { PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 }; 768 1.1 christos model_busy *busy_ptr; 769 1.1 christos 770 1.1 christos for (f = 0; f < 8; f++) { 771 1.1 christos if (FXM & (0x80 >> f)) { 772 1.1 christos cr_mask |= (1 << f); 773 1.1 christos nr_crs++; 774 1.1 christos } 775 1.1 christos } 776 1.1 christos 777 1.1 christos while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) { 778 1.1 christos if (WITH_TRACE && ppc_trace[trace_model]) 779 1.1 christos model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR); 780 1.1 christos 781 1.1 christos model_ptr->nr_stalls_data++; 782 1.1 christos model_new_cycle(model_ptr); 783 1.1 christos } 784 1.1 christos 785 1.1 christos /* If only one CR is being moved, use the SCIU, not the MCIU on the 604 */ 786 1.1 christos if (CURRENT_MODEL == MODEL_ppc604 && nr_crs == 1) { 787 1.1 christos normal_time = &ppc604_1bit_time; 788 1.1 christos } 789 1.1 christos 790 1.1 christos busy_ptr = model_wait_for_unit(index, model_ptr, normal_time); 791 1.1 christos busy_ptr->cr_fpscr_busy |= cr_mask; 792 1.1 christos model_ptr->cr_fpscr_busy |= cr_mask; 793 1.1 christos model_ptr->nr_mtcrf_crs[nr_crs]++; 794 1.1 christos busy_ptr->nr_writebacks = 1; 795 1.1 christos if (WITH_TRACE && ppc_trace[trace_model]) 796 1.1 christos model_trace_make_busy(model_ptr, 0, 0, cr_mask); 797 1.1 christos 799 1.1 christos model_data *::model-function::model_create:cpu *processor 800 1.1 christos model_data *model_ptr = ZALLOC(model_data); 801 1.1 christos model_ptr->name = model_name[CURRENT_MODEL]; 802 1.1 christos model_ptr->timing = model_time_mapping[CURRENT_MODEL]; 803 1.1 christos model_ptr->processor = processor; 804 1.1 christos model_ptr->nr_cycles = 1; 805 1.1 christos model_ptr->busy_tail = &model_ptr->busy_head; 806 1.1 christos switch (CURRENT_MODEL) { 807 1.1 christos case MODEL_ppc601: model_ptr->max_nr_writebacks = 1; break; /* ??? */ 808 1.1 christos case MODEL_ppc603: model_ptr->max_nr_writebacks = 2; break; 809 1.1 christos case MODEL_ppc603e: model_ptr->max_nr_writebacks = 2; break; 810 1.1 christos case MODEL_ppc604: model_ptr->max_nr_writebacks = 2; break; 811 1.1 christos default: error ("Unknown model %d\n", CURRENT_MODEL); 812 1.1 christos } 813 1.1 christos return model_ptr; 814 1.1 christos 815 1.1 christos void::model-function::model_init:model_data *model_ptr 816 1.1 christos 817 1.1 christos void::model-function::model_halt:model_data *model_ptr 818 1.1 christos /* Let pipeline drain */ 819 1.1 christos while (model_ptr->busy_head.next) 820 1.1 christos model_new_cycle(model_ptr); 821 1.1 christos 822 1.1 christos unsigned_word::model-function::model_get_number_of_stalls:model_data *model_ptr 823 1.1 christos return (model_ptr->nr_stalls_data 824 1.1 christos + model_ptr->nr_stalls_unit 825 1.1 christos + model_ptr->nr_stalls_serialize 826 1.1 christos + model_ptr->nr_stalls_writeback); 827 1.1 christos 828 1.1 christos unsigned_word::model-function::model_get_number_of_cycles:model_data *model_ptr 829 1.1 christos return (model_ptr->nr_cycles); 830 1.1 christos 831 1.1 christos model_print *::model-function::model_mon_info:model_data *model_ptr 832 1.1 christos model_print *head; 833 1.1 christos model_print *tail; 834 1.1 christos ppc_function_unit i; 835 1.1 christos count_type nr_insns; 836 1.1 christos int j; 837 1.1 christos 838 1.1 christos head = tail = ZALLOC(model_print); 839 1.1 christos tail->count = model_ptr->nr_cycles; 840 1.1 christos tail->name = "cycle"; 841 1.1 christos tail->suffix_plural = "s"; 842 1.1 christos tail->suffix_singular = ""; 843 1.1 christos 844 1.1 christos if (model_ptr->nr_stalls_data) { 845 1.1 christos tail->next = ZALLOC(model_print); 846 1.1 christos tail = tail->next; 847 1.1 christos tail->count = model_ptr->nr_stalls_data; 848 1.1 christos tail->name = "stall"; 849 1.1 christos tail->suffix_plural = "s waiting for data"; 850 1.1 christos tail->suffix_singular = " waiting for data"; 851 1.1 christos } 852 1.1 christos 853 1.1 christos if (model_ptr->nr_stalls_unit) { 854 1.1 christos tail->next = ZALLOC(model_print); 855 1.1 christos tail = tail->next; 856 1.1 christos tail->count = model_ptr->nr_stalls_unit; 857 1.1 christos tail->name = "stall"; 858 1.1 christos tail->suffix_plural = "s waiting for a function unit"; 859 1.1 christos tail->suffix_singular = " waiting for a function unit"; 860 1.1 christos } 861 1.1 christos 862 1.1 christos if (model_ptr->nr_stalls_serialize) { 863 1.1 christos tail->next = ZALLOC(model_print); 864 1.1 christos tail = tail->next; 865 1.1 christos tail->count = model_ptr->nr_stalls_serialize; 866 1.1 christos tail->name = "stall"; 867 1.1 christos tail->suffix_plural = "s waiting for serialization"; 868 1.1 christos tail->suffix_singular = " waiting for serialization"; 869 1.1 christos } 870 1.1 christos 871 1.1 christos if (model_ptr->nr_stalls_writeback) { 872 1.1 christos tail->next = ZALLOC(model_print); 873 1.1 christos tail = tail->next; 874 1.1 christos tail->count = model_ptr->nr_stalls_writeback; 875 1.1 christos tail->name = ""; 876 1.1 christos tail->suffix_plural = "times a write-back slot was unavailable"; 877 1.1 christos tail->suffix_singular = "time a writeback was unavailable"; 878 1.1 christos } 879 1.1 christos 880 1.1 christos if (model_ptr->nr_branches) { 881 1.1 christos tail->next = ZALLOC(model_print); 882 1.1 christos tail = tail->next; 883 1.1 christos tail->count = model_ptr->nr_branches; 884 1.1 christos tail->name = "branch"; 885 1.1 christos tail->suffix_plural = "es"; 886 1.1 christos tail->suffix_singular = ""; 887 1.1 christos } 888 1.1 christos 889 1.1 christos if (model_ptr->nr_branches_fallthrough) { 890 1.1 christos tail->next = ZALLOC(model_print); 891 1.1 christos tail = tail->next; 892 1.1 christos tail->count = model_ptr->nr_branches_fallthrough; 893 1.1 christos tail->name = "conditional branch"; 894 1.1 christos tail->suffix_plural = "es fell through"; 895 1.1 christos tail->suffix_singular = " fell through"; 896 1.1 christos } 897 1.1 christos 898 1.1 christos if (model_ptr->nr_branch_predict_trues) { 899 1.1 christos tail->next = ZALLOC(model_print); 900 1.1 christos tail = tail->next; 901 1.1 christos tail->count = model_ptr->nr_branch_predict_trues; 902 1.1 christos tail->name = "successful branch prediction"; 903 1.1 christos tail->suffix_plural = "s"; 904 1.1 christos tail->suffix_singular = ""; 905 1.1 christos } 906 1.1 christos 907 1.1 christos if (model_ptr->nr_branch_predict_falses) { 908 1.1 christos tail->next = ZALLOC(model_print); 909 1.1 christos tail = tail->next; 910 1.1 christos tail->count = model_ptr->nr_branch_predict_falses; 911 1.1 christos tail->name = "unsuccessful branch prediction"; 912 1.1 christos tail->suffix_plural = "s"; 913 1.1 christos tail->suffix_singular = ""; 914 1.1 christos } 915 1.1 christos 916 1.1 christos for (j = 0; j < ARRAY_SIZE (ppc_branch_conditional_name); j++) { 917 1.1 christos if (model_ptr->nr_branch_conditional[j]) { 918 1.1 christos tail->next = ZALLOC(model_print); 919 1.1 christos tail = tail->next; 920 1.1 christos tail->count = model_ptr->nr_branch_conditional[j]; 921 1.1 christos tail->name = ppc_branch_conditional_name[j]; 922 1.1 christos tail->suffix_plural = " conditional branches"; 923 1.1 christos tail->suffix_singular = " conditional branch"; 924 1.1 christos } 925 1.1 christos } 926 1.1 christos 927 1.1 christos for (j = 0; j < 9; j++) { 928 1.1 christos if (model_ptr->nr_mtcrf_crs[j]) { 929 1.1 christos tail->next = ZALLOC(model_print); 930 1.1 christos tail = tail->next; 931 1.1 christos tail->count = model_ptr->nr_mtcrf_crs[j]; 932 1.1 christos tail->name = ppc_nr_mtcrf_crs[j]; 933 1.1 christos tail->suffix_plural = " instructions"; 934 1.1 christos tail->suffix_singular = " instruction"; 935 1.1 christos } 936 1.1 christos } 937 1.1 christos 938 1.1 christos nr_insns = 0; 939 1.1 christos for (i = PPC_UNIT_BAD; i < nr_ppc_function_units; i++) { 940 1.1 christos if (model_ptr->nr_units[i]) { 941 1.1 christos nr_insns += model_ptr->nr_units[i]; 942 1.1 christos tail->next = ZALLOC(model_print); 943 1.1 christos tail = tail->next; 944 1.1 christos tail->count = model_ptr->nr_units[i]; 945 1.1 christos tail->name = ppc_function_unit_name[i]; 946 1.1 christos tail->suffix_plural = "s"; 947 1.1 christos tail->suffix_singular = ""; 948 1.1 christos } 949 1.1 christos } 950 1.1 christos 951 1.1 christos tail->next = ZALLOC(model_print); 952 1.1 christos tail = tail->next; 953 1.1 christos tail->count = nr_insns; 954 1.1 christos tail->name = "instruction"; 955 1.1 christos tail->suffix_plural = "s that were accounted for in timing info"; 956 1.1 christos tail->suffix_singular = " that was accounted for in timing info"; 957 1.1 christos 958 1.1 christos tail->next = (model_print *)0; 959 1.1 christos return head; 960 1.1 christos 961 1.1 christos void::model-function::model_mon_info_free:model_data *model_ptr, model_print *ptr 962 1.1 christos while (ptr) { 963 1.1 christos model_print *next = ptr->next; 964 1.1 christos free((void *)ptr); 965 1.1 christos ptr = next; 966 1.1 christos } 967 1.1 christos 968 1.1 christos void::model-function::model_branches:model_data *model_ptr, int failed, int conditional 969 1.1 christos model_ptr->nr_units[PPC_UNIT_BPU]++; 970 1.1 christos if (failed) 971 1.1 christos model_ptr->nr_branches_fallthrough++; 972 1.1 christos else 973 1.1 christos model_ptr->nr_branches++; 974 1.1 christos if (conditional >= 0) 975 1.1 christos model_ptr->nr_branch_conditional[conditional]++; 976 1.1 christos model_new_cycle(model_ptr); /* A branch always ends the current cycle */ 977 1.1 christos 978 1.1 christos void::model-function::model_branch_predict:model_data *model_ptr, int success 979 1.1 christos if (success) 980 1.1 christos model_ptr->nr_branch_predict_trues++; 981 1.1 christos else 982 1.1 christos model_ptr->nr_branch_predict_falses++; 983 1.1 christos 984 1.1 christos 986 1.1 christos # The following (illegal) instruction is `known' by gen and is 987 1.1 christos # called when ever an illegal instruction is encountered 988 1.1 christos ::internal::illegal 989 1.1 christos program_interrupt(processor, cia, 990 1.1 christos illegal_instruction_program_interrupt); 991 1.1 christos 992 1.1 christos 993 1.1 christos # The following (floating point unavailable) instruction is `known' by gen 994 1.1 christos # and is called when ever an a floating point instruction is to be 995 1.1 christos # executed but floating point is make unavailable by the MSR 996 1.1 christos ::internal::floating_point_unavailable 997 1.1 christos floating_point_unavailable_interrupt(processor, cia); 998 1.1 christos 999 1.1 christos 1000 1.1 christos # 1001 1.1 christos # Floating point support functions 1002 1.1 christos # 1003 1.1 christos 1004 1.1 christos # Convert 32bit single to 64bit double 1005 1.1 christos uint64_t::function::DOUBLE:uint32_t WORD 1006 1.1 christos uint64_t FRT; 1007 1.1 christos if (EXTRACTED32(WORD, 1, 8) > 0 1008 1.1 christos && EXTRACTED32(WORD, 1, 8) < 255) { 1009 1.1 christos /* normalized operand */ 1010 1.1 christos int not_word_1_1 = !EXTRACTED32(WORD, 1, 1); /*2.6.3 bug*/ 1011 1.1 christos FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1) 1012 1.1 christos | INSERTED64(not_word_1_1, 2, 2) 1013 1.1 christos | INSERTED64(not_word_1_1, 3, 3) 1014 1.1 christos | INSERTED64(not_word_1_1, 4, 4) 1015 1.1 christos | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29))); 1016 1.1 christos } 1017 1.1 christos else if (EXTRACTED32(WORD, 1, 8) == 0 1018 1.1 christos && EXTRACTED32(WORD, 9, 31) != 0) { 1019 1.1 christos /* denormalized operand */ 1020 1.1 christos int sign = EXTRACTED32(WORD, 0, 0); 1021 1.1 christos int exp = -126; 1022 1.1 christos uint64_t frac = INSERTED64(EXTRACTED32(WORD, 9, 31), 1, (52 - 29)); 1023 1.1 christos /* normalize the operand */ 1024 1.1 christos while (MASKED64(frac, 0, 0) == 0) { 1025 1.1 christos frac <<= 1; 1026 1.1 christos exp -= 1; 1027 1.1 christos } 1028 1.1 christos FRT = (INSERTED64(sign, 0, 0) 1029 1.1 christos | INSERTED64(exp + 1023, 1, 11) 1030 1.1 christos | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63)); 1031 1.1 christos } 1032 1.1 christos else if (EXTRACTED32(WORD, 1, 8) == 255 1033 1.1 christos || EXTRACTED32(WORD, 1, 31) == 0) { 1034 1.1 christos FRT = (INSERTED64(EXTRACTED32(WORD, 0, 1), 0, 1) 1035 1.1 christos | INSERTED64(EXTRACTED32(WORD, 1, 1), 2, 2) 1036 1.1 christos | INSERTED64(EXTRACTED32(WORD, 1, 1), 3, 3) 1037 1.1 christos | INSERTED64(EXTRACTED32(WORD, 1, 1), 4, 4) 1038 1.1 christos | INSERTED64(EXTRACTED32(WORD, 2, 31), 5, (63 - 29))); 1039 1.1 christos } 1040 1.1 christos else { 1041 1.1 christos error("DOUBLE - unknown case\n"); 1042 1.1 christos FRT = 0; 1043 1.1 christos } 1044 1.1 christos return FRT; 1045 1.1 christos 1046 1.1 christos # Convert 64bit single to 32bit double 1047 1.1 christos uint32_t::function::SINGLE:uint64_t FRS 1048 1.1 christos uint32_t WORD; 1049 1.1 christos if (EXTRACTED64(FRS, 1, 11) > 896 1050 1.1 christos || EXTRACTED64(FRS, 1, 63) == 0) { 1051 1.1 christos /* no denormalization required (includes Zero/Infinity/NaN) */ 1052 1.1 christos WORD = (INSERTED32(EXTRACTED64(FRS, 0, 1), 0, 1) 1053 1.1 christos | INSERTED32(EXTRACTED64(FRS, 5, 34), 2, 31)); 1054 1.1 christos } 1055 1.1 christos else if (874 <= EXTRACTED64(FRS, 1, 11) 1056 1.1 christos && EXTRACTED64(FRS, 1, 11) <= 896) { 1057 1.1 christos /* denormalization required */ 1058 1.1 christos int sign = EXTRACTED64(FRS, 0, 0); 1059 1.1 christos int exp = EXTRACTED64(FRS, 1, 11) - 1023; 1060 1.1 christos uint64_t frac = (BIT64(0) 1061 1.1 christos | INSERTED64(EXTRACTED64(FRS, 12, 63), 1, 52)); 1062 1.1 christos /* denormalize the operand */ 1063 1.1 christos while (exp < -126) { 1064 1.1 christos frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63); 1065 1.1 christos exp += 1; 1066 1.1 christos } 1067 1.1 christos WORD = (INSERTED32(sign, 0, 0) 1068 1.1 christos | INSERTED32(0x00, 1, 8) 1069 1.1 christos | INSERTED32(EXTRACTED64(frac, 1, 23), 9, 31)); 1070 1.1 christos } 1071 1.1 christos else { 1072 1.1 christos WORD = 0x0; /* ??? */ 1073 1.1 christos } 1074 1.1 christos return WORD; 1075 1.1 christos 1076 1.1 christos 1077 1.1 christos # round 64bit double to 64bit but single 1078 1.1 christos void::function::Round_Single:cpu *processor, int sign, int *exp, uint64_t *frac_grx 1079 1.1 christos /* comparisons ignore u bits */ 1080 1.1 christos uint64_t out; 1081 1.1 christos int inc = 0; 1082 1.1 christos int lsb = EXTRACTED64(*frac_grx, 23, 23); 1083 1.1 christos int gbit = EXTRACTED64(*frac_grx, 24, 24); 1084 1.1 christos int rbit = EXTRACTED64(*frac_grx, 25, 25); 1085 1.1 christos int xbit = EXTRACTED64(*frac_grx, 26, 55) != 0; 1086 1.1 christos if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) { 1087 1.1 christos if (lsb == 1 && gbit == 1) inc = 1; 1088 1.1 christos if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1; 1089 1.1 christos if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1; 1090 1.1 christos } 1091 1.1 christos if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) { 1092 1.1 christos if (sign == 0 && gbit == 1) inc = 1; 1093 1.1 christos if (sign == 0 && rbit == 1) inc = 1; 1094 1.1 christos if (sign == 0 && xbit == 1) inc = 1; 1095 1.1 christos } 1096 1.1 christos if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) { 1097 1.1 christos if (sign == 1 && gbit == 1) inc = 1; 1098 1.1 christos if (sign == 1 && rbit == 1) inc = 1; 1099 1.1 christos if (sign == 1 && xbit == 1) inc = 1; 1100 1.1 christos } 1101 1.1 christos /* work out addition in low 25 bits of out */ 1102 1.1 christos out = EXTRACTED64(*frac_grx, 0, 23) + inc; 1103 1.1 christos *frac_grx = INSERTED64(out, 0, 23); 1104 1.1 christos if (out & BIT64(64 - 23 - 1 - 1)) { 1105 1.1 christos *frac_grx = (BIT64(0) | 1106 1.1 christos INSERTED64(EXTRACTED64(*frac_grx, 0, 22), 1, 23)); 1107 1.1 christos *exp = *exp + 1; 1108 1.1 christos } 1109 1.1 christos /* frac_grx[24:52] = 0 already */ 1110 1.1 christos FPSCR_SET_FR(inc); 1111 1.1 christos FPSCR_SET_FI(gbit || rbit || xbit); 1112 1.1 christos 1113 1.1 christos 1114 1.1 christos # 1115 1.1 christos void::function::Round_Integer:cpu *processor, int sign, uint64_t *frac, int *frac64, int gbit, int rbit, int xbit, fpscreg round_mode 1116 1.1 christos int inc = 0; 1117 1.1 christos if (round_mode == fpscr_rn_round_to_nearest) { 1118 1.1 christos if (*frac64 == 1 && gbit == 1) inc = 1; 1119 1.1 christos if (*frac64 == 0 && gbit == 1 && rbit == 1) inc = 1; 1120 1.1 christos if (*frac64 == 0 && gbit == 1 && xbit == 1) inc = 1; 1121 1.1 christos } 1122 1.1 christos if (round_mode == fpscr_rn_round_towards_pos_infinity) { 1123 1.1 christos if (sign == 0 && gbit == 1) inc = 1; 1124 1.1 christos if (sign == 0 && rbit == 1) inc = 1; 1125 1.1 christos if (sign == 0 && xbit == 1) inc = 1; 1126 1.1 christos } 1127 1.1 christos if (round_mode == fpscr_rn_round_towards_neg_infinity) { 1128 1.1 christos if (sign == 1 && gbit == 1) inc = 1; 1129 1.1 christos if (sign == 1 && rbit == 1) inc = 1; 1130 1.1 christos if (sign == 1 && xbit == 1) inc = 1; 1131 1.1 christos } 1132 1.1 christos /* frac[0:64] = frac[0:64} + inc */ 1133 1.1 christos *frac += (*frac64 && inc ? 1 : 0); 1134 1.1 christos *frac64 = (*frac64 + inc) & 0x1; 1135 1.1 christos FPSCR_SET_FR(inc); 1136 1.1 christos FPSCR_SET_FI(gbit | rbit | xbit); 1137 1.1 christos 1138 1.1 christos 1139 1.1 christos void::function::Round_Float:cpu *processor, int sign, int *exp, uint64_t *frac, fpscreg round_mode 1140 1.1 christos int carry_out; 1141 1.1 christos int inc = 0; 1142 1.1 christos int lsb = EXTRACTED64(*frac, 52, 52); 1143 1.1 christos int gbit = EXTRACTED64(*frac, 53, 53); 1144 1.1 christos int rbit = EXTRACTED64(*frac, 54, 54); 1145 1.1 christos int xbit = EXTRACTED64(*frac, 55, 55); 1146 1.1 christos if (round_mode == fpscr_rn_round_to_nearest) { 1147 1.1 christos if (lsb == 1 && gbit == 1) inc = 1; 1148 1.1 christos if (lsb == 0 && gbit == 1 && rbit == 1) inc = 1; 1149 1.1 christos if (lsb == 0 && gbit == 1 && xbit == 1) inc = 1; 1150 1.1 christos } 1151 1.1 christos if (round_mode == fpscr_rn_round_towards_pos_infinity) { 1152 1.1 christos if (sign == 0 && gbit == 1) inc = 1; 1153 1.1 christos if (sign == 0 && rbit == 1) inc = 1; 1154 1.1 christos if (sign == 0 && xbit == 1) inc = 1; 1155 1.1 christos } 1156 1.1 christos if (round_mode == fpscr_rn_round_towards_neg_infinity) { 1157 1.1 christos if (sign == 1 && gbit == 1) inc = 1; 1158 1.1 christos if (sign == 1 && rbit == 1) inc = 1; 1159 1.1 christos if (sign == 1 && xbit == 1) inc = 1; 1160 1.1 christos } 1161 1.1 christos /* frac//carry_out = frac + inc */ 1162 1.1 christos *frac = (*frac >> 1) + (INSERTED64(inc, 52, 52) >> 1); 1163 1.1 christos carry_out = EXTRACTED64(*frac, 0, 0); 1164 1.1 christos *frac <<= 1; 1165 1.1 christos if (carry_out == 1) *exp = *exp + 1; 1166 1.1 christos FPSCR_SET_FR(inc); 1167 1.1 christos FPSCR_SET_FI(gbit | rbit | xbit); 1168 1.1 christos FPSCR_SET_XX(FPSCR & fpscr_fi); 1169 1.1 christos 1170 1.1 christos 1171 1.1 christos # conversion of FP to integer 1172 1.1 christos void::function::convert_to_integer:cpu *processor, unsigned_word cia, uint64_t *frt, uint64_t frb, fpscreg round_mode, int tgt_precision 1173 1.1 christos int i; 1174 1.1 christos int exp = 0; 1175 1.1 christos uint64_t frac = 0; 1176 1.1 christos int frac64 = 0; 1177 1.1 christos int gbit = 0; 1178 1.1 christos int rbit = 0; 1179 1.1 christos int xbit = 0; 1180 1.1 christos int sign = EXTRACTED64(frb, 0, 0); 1181 1.1 christos /***/ 1182 1.1 christos if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 63) == 0) 1183 1.1 christos GOTO(Infinity_Operand); 1184 1.1 christos if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 0) 1185 1.1 christos GOTO(SNaN_Operand); 1186 1.1 christos if (EXTRACTED64(frb, 1, 11) == 2047 && EXTRACTED64(frb, 12, 12) == 1) 1187 1.1 christos GOTO(QNaN_Operand); 1188 1.1 christos if (EXTRACTED64(frb, 1, 11) > 1086) GOTO(Large_Operand); 1189 1.1 christos if (EXTRACTED64(frb, 1, 11) > 0) exp = EXTRACTED64(frb, 1, 11) - 1023; 1190 1.1 christos if (EXTRACTED64(frb, 1, 11) == 0) exp = -1022; 1191 1.1 christos if (EXTRACTED64(frb, 1, 11) > 0) { /* normal */ 1192 1.1 christos frac = BIT64(1) | INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53); 1193 1.1 christos frac64 = 0; 1194 1.1 christos } 1195 1.1 christos if (EXTRACTED64(frb, 1, 11) == 0) { /* denorm */ 1196 1.1 christos frac = INSERTED64(EXTRACTED64(frb, 12, 63), 2, 53); 1197 1.1 christos frac64 = 0; 1198 1.1 christos } 1199 1.1 christos gbit = 0, rbit = 0, xbit = 0; 1200 1.1 christos for (i = 1; i <= 63 - exp; i++) { 1201 1.1 christos xbit = rbit | xbit; 1202 1.1 christos rbit = gbit; 1203 1.1 christos gbit = frac64; 1204 1.1 christos frac64 = EXTRACTED64(frac, 63, 63); 1205 1.1 christos frac = INSERTED64(EXTRACTED64(frac, 0, 62), 1, 63); 1206 1.1 christos } 1207 1.1 christos Round_Integer(processor, sign, &frac, &frac64, gbit, rbit, xbit, round_mode); 1208 1.1 christos if (sign == 1) { /* frac[0:64] = ~frac[0:64] + 1 */ 1209 1.1 christos frac = ~frac; 1210 1.1 christos frac64 ^= 1; 1211 1.1 christos frac += (frac64 ? 1 : 0); 1212 1.1 christos frac64 = (frac64 + 1) & 0x1; 1213 1.1 christos } 1214 1.1 christos if (tgt_precision == 32 /* can ignore frac64 in compare */ 1215 1.1 christos && (int64_t)frac > (int64_t)MASK64(33+1, 63)/*2^31-1 >>1*/) 1216 1.1 christos GOTO(Large_Operand); 1217 1.1 christos if (tgt_precision == 64 /* can ignore frac64 in compare */ 1218 1.1 christos && (int64_t)frac > (int64_t)MASK64(1+1, 63)/*2^63-1 >>1*/) 1219 1.1 christos GOTO(Large_Operand); 1220 1.1 christos if (tgt_precision == 32 /* can ignore frac64 in compare */ 1221 1.1 christos && (int64_t)frac < (int64_t)MASK64(0, 32+1)/*-2^31 >>1*/) 1222 1.1 christos GOTO(Large_Operand); 1223 1.1 christos if (tgt_precision == 64 /* can ignore frac64 in compare */ 1224 1.1 christos && (int64_t)frac < (int64_t)MASK64(0, 0+1)/*-2^63 >>1*/) 1225 1.1 christos GOTO(Large_Operand); 1226 1.1 christos FPSCR_SET_XX(FPSCR & fpscr_fi); 1227 1.1 christos if (tgt_precision == 32) 1228 1.1 christos *frt = MASKED64(*frt, 0, 31) | (EXTRACTED64(frac, 33, 63) << 1) | frac64; 1229 1.1 christos if (tgt_precision == 64) 1230 1.1 christos *frt = (EXTRACTED64(frac, 1, 63) << 1) | frac64; 1231 1.1 christos /*FPSCR[fprf] = undefined */ 1232 1.1 christos GOTO(Done); 1233 1.1 christos /**/ 1234 1.1 christos LABEL(Infinity_Operand): 1235 1.1 christos FPSCR_SET_FR(0); 1236 1.1 christos FPSCR_SET_FI(0); 1237 1.1 christos FPSCR_OR_VX(fpscr_vxcvi); 1238 1.1 christos if ((FPSCR & fpscr_ve) == 0) { 1239 1.1 christos if (tgt_precision == 32) { 1240 1.1 christos if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7FFFFFFF; 1241 1.1 christos if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000; 1242 1.1 christos } 1243 1.1 christos else { 1244 1.1 christos if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/ 1245 1.1 christos if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/ 1246 1.1 christos } 1247 1.1 christos /* FPSCR[FPRF] = undefined */ 1248 1.1 christos } 1249 1.1 christos GOTO(Done); 1250 1.1 christos /**/ 1251 1.1 christos LABEL(SNaN_Operand): 1252 1.1 christos FPSCR_SET_FR(0); 1253 1.1 christos FPSCR_SET_FI(0); 1254 1.1 christos FPSCR_OR_VX(fpscr_vxsnan | fpscr_vxcvi); 1255 1.1 christos if ((FPSCR & fpscr_ve) == 0) { 1256 1.1 christos if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000; 1257 1.1 christos if (tgt_precision == 64) *frt = BIT64(0); /*0x8000_0000_0000_0000*/ 1258 1.1 christos /* FPSCR[fprf] = undefined */ 1259 1.1 christos } 1260 1.1 christos GOTO(Done); 1261 1.1 christos /**/ 1262 1.1 christos LABEL(QNaN_Operand): 1263 1.1 christos FPSCR_SET_FR(0); 1264 1.1 christos FPSCR_SET_FI(0); 1265 1.1 christos FPSCR_OR_VX(fpscr_vxcvi); 1266 1.1 christos if ((FPSCR & fpscr_ve) == 0) { 1267 1.1 christos if (tgt_precision == 32) *frt = MASKED64(*frt, 0, 31) | 0x80000000; 1268 1.1 christos if (tgt_precision == 64) *frt = BIT64(0);/*0x8000_0000_0000_0000*/ 1269 1.1 christos /* FPSCR[fprf] = undefined */ 1270 1.1 christos } 1271 1.1 christos GOTO(Done); 1272 1.1 christos /**/ 1273 1.1 christos LABEL(Large_Operand): 1274 1.1 christos FPSCR_SET_FR(0); 1275 1.1 christos FPSCR_SET_FI(0); 1276 1.1 christos FPSCR_OR_VX(fpscr_vxcvi); 1277 1.1 christos if ((FPSCR & fpscr_ve) == 0) { 1278 1.1 christos if (tgt_precision == 32) { 1279 1.1 christos if (sign == 0) *frt = MASKED64(*frt, 0, 31) | 0x7fffffff; 1280 1.1 christos if (sign == 1) *frt = MASKED64(*frt, 0, 31) | 0x80000000; 1281 1.1 christos } 1282 1.1 christos else { 1283 1.1 christos if (sign == 0) *frt = MASK64(1, 63); /*0x7FFF_FFFF_FFFF_FFFF*/ 1284 1.1 christos if (sign == 1) *frt = BIT64(0); /*0x8000_0000_0000_0000*/ 1285 1.1 christos } 1286 1.1 christos /* FPSCR[fprf] = undefined */ 1287 1.1 christos } 1288 1.1 christos /**/ 1289 1.1 christos LABEL(Done):; 1290 1.1 christos 1291 1.1 christos 1292 1.1 christos # extract out raw fields of a FP number 1293 1.1 christos int::function::sign:uint64_t FRS 1294 1.1 christos return (MASKED64(FRS, 0, 0) 1295 1.1 christos ? -1 1296 1.1 christos : 1); 1297 1.1 christos int::function::biased_exp:uint64_t frs, int single 1298 1.1 christos if (single) 1299 1.1 christos return EXTRACTED64(frs, 1, 8); 1300 1.1 christos else 1301 1.1 christos return EXTRACTED64(frs, 1, 11); 1302 1.1 christos uint64_t::function::fraction:uint64_t frs, int single 1303 1.1 christos if (single) 1304 1.1 christos return EXTRACTED64(frs, 9, 31); 1305 1.1 christos else 1306 1.1 christos return EXTRACTED64(frs, 12, 63); 1307 1.1 christos 1308 1.1 christos # a number?, each of the below return +1 or -1 (based on sign bit) 1309 1.1 christos # if true. 1310 1.1 christos int::function::is_nor:uint64_t frs, int single 1311 1.1 christos int exp = biased_exp(frs, single); 1312 1.1 christos return (exp >= 1 1313 1.1 christos && exp <= (single ? 254 : 2046)); 1314 1.1 christos int::function::is_zero:uint64_t FRS 1315 1.1 christos return (MASKED64(FRS, 1, 63) == 0 1316 1.1 christos ? sign(FRS) 1317 1.1 christos : 0); 1318 1.1 christos int::function::is_den:uint64_t frs, int single 1319 1.1 christos int exp = biased_exp(frs, single); 1320 1.1 christos uint64_t frac = fraction(frs, single); 1321 1.1 christos return (exp == 0 && frac != 0 1322 1.1 christos ? sign(frs) 1323 1.1 christos : 0); 1324 1.1 christos int::function::is_inf:uint64_t frs, int single 1325 1.1 christos int exp = biased_exp(frs, single); 1326 1.1 christos uint64_t frac = fraction(frs, single); 1327 1.1 christos return (exp == (single ? 255 : 2047) && frac == 0 1328 1.1 christos ? sign(frs) 1329 1.1 christos : 0); 1330 1.1 christos int::function::is_NaN:uint64_t frs, int single 1331 1.1 christos int exp = biased_exp(frs, single); 1332 1.1 christos uint64_t frac = fraction(frs, single); 1333 1.1 christos return (exp == (single ? 255 : 2047) && frac != 0 1334 1.1 christos ? sign(frs) 1335 1.1 christos : 0); 1336 1.1 christos int::function::is_SNaN:uint64_t frs, int single 1337 1.1 christos return (is_NaN(frs, single) 1338 1.1 christos && !(frs & (single ? MASK64(9, 9) : MASK64(12, 12))) 1339 1.1 christos ? sign(frs) 1340 1.1 christos : 0); 1341 1.1 christos int::function::is_QNaN:uint64_t frs, int single 1342 1.1 christos return (is_NaN(frs, single) && !is_SNaN(frs, single)); 1343 1.1 christos int::function::is_less_than:uint64_t *fra, uint64_t *frb 1344 1.1 christos return *(double*)fra < *(double*)frb; 1345 1.1 christos int::function::is_greater_than:uint64_t *fra, uint64_t *frb 1346 1.1 christos return *(double*)fra > *(double*)frb; 1347 1.1 christos int::function::is_equan_to:uint64_t *fra, uint64_t *frb 1348 1.1 christos return *(double*)fra == *(double*)frb; 1349 1.1 christos 1350 1.1 christos 1351 1.1 christos # which quiet nan should become the result 1352 1.1 christos uint64_t::function::select_qnan:uint64_t fra, uint64_t frb, uint64_t frc, int instruction_is_frsp, int generate_qnan, int single 1353 1.1 christos uint64_t frt = 0; 1354 1.1 christos if (is_NaN(fra, single)) 1355 1.1 christos frt = fra; 1356 1.1 christos else if (is_NaN(frb, single)) 1357 1.1 christos if (instruction_is_frsp) 1358 1.1 christos frt = MASKED64(frb, 0, 34); 1359 1.1 christos else 1360 1.1 christos frt = frb; 1361 1.1 christos else if (is_NaN(frc, single)) 1362 1.1 christos frt = frc; 1363 1.1 christos else if (generate_qnan) 1364 1.1 christos frt = MASK64(1, 12); /* 0x7FF8_0000_0000_0000 */ 1365 1.1 christos else 1366 1.1 christos error("select_qnan - default reached\n"); 1367 1.1 christos return frt; 1368 1.1 christos 1369 1.1 christos 1370 1.1 christos # detect invalid operation 1371 1.1 christos int::function::is_invalid_operation:cpu *processor, unsigned_word cia, uint64_t fra, uint64_t frb, fpscreg check, int single, int negate 1372 1.1 christos int fail = 0; 1373 1.1 christos if ((check & fpscr_vxsnan) 1374 1.1 christos && (is_SNaN(fra, single) || is_SNaN(frb, single))) { 1375 1.1 christos FPSCR_OR_VX(fpscr_vxsnan); 1376 1.1 christos fail = 1; 1377 1.1 christos } 1378 1.1 christos if ((check & fpscr_vxisi) 1379 1.1 christos && (is_inf(fra, single) && is_inf(frb, single)) 1380 1.1 christos && ((negate && sign(fra) != sign(frb)) 1381 1.1 christos || (!negate && sign(fra) == sign(frb)))) { 1382 1.1 christos /*FIXME: don't handle inf-inf VS inf+-inf */ 1383 1.1 christos FPSCR_OR_VX(fpscr_vxisi); 1384 1.1 christos fail = 1; 1385 1.1 christos } 1386 1.1 christos if ((check & fpscr_vxidi) 1387 1.1 christos && (is_inf(fra, single) && is_inf(frb, single))) { 1388 1.1 christos FPSCR_OR_VX(fpscr_vxidi); 1389 1.1 christos fail = 1; 1390 1.1 christos } 1391 1.1 christos if ((check & fpscr_vxzdz) 1392 1.1 christos && (is_zero(fra) && is_zero(frb))) { 1393 1.1 christos FPSCR_OR_VX(fpscr_vxzdz); 1394 1.1 christos fail = 1; 1395 1.1 christos } 1396 1.1 christos if ((check & fpscr_vximz) 1397 1.1 christos && (is_zero(fra) && is_inf(frb, single))) { 1398 1.1 christos FPSCR_OR_VX(fpscr_vximz); 1399 1.1 christos fail = 1; 1400 1.1 christos } 1401 1.1 christos if ((check & fpscr_vxvc) 1402 1.1 christos && (is_NaN(fra, single) || is_NaN(frb, single))) { 1403 1.1 christos FPSCR_OR_VX(fpscr_vxvc); 1404 1.1 christos fail = 1; 1405 1.1 christos } 1406 1.1 christos if ((check & fpscr_vxsoft)) { 1407 1.1 christos FPSCR_OR_VX(fpscr_vxsoft); 1408 1.1 christos fail = 1; 1409 1.1 christos } 1410 1.1 christos if ((check & fpscr_vxsqrt) 1411 1.1 christos && sign(fra) < 0) { 1412 1.1 christos FPSCR_OR_VX(fpscr_vxsqrt); 1413 1.1 christos fail = 1; 1414 1.1 christos } 1415 1.1 christos /* if ((check && fpscr_vxcvi) { 1416 1.1 christos && (is_inf(fra, single) || is_NaN(fra, single) || is_large(fra, single))) 1417 1.1 christos FPSCR_OR_VX(fpscr_vxcvi); 1418 1.1 christos fail = 1; 1419 1.1 christos } 1420 1.1 christos */ 1421 1.1 christos return fail; 1422 1.1 christos 1423 1.1 christos 1424 1.1 christos 1425 1.1 christos 1426 1.1 christos 1427 1.1 christos # handle case of invalid operation 1428 1.1 christos void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, uint64_t *frt, uint64_t fra, uint64_t frb, uint64_t frc, int instruction_is_frsp, int instruction_is_convert_to_64bit, int instruction_is_convert_to_32bit, int single 1429 1.1 christos if (FPSCR & fpscr_ve) { 1430 1.1 christos /* invalid operation exception enabled */ 1431 1.1 christos /* FRT unchaged */ 1432 1.1 christos FPSCR_SET_FR(0); 1433 1.1 christos FPSCR_SET_FI(0); 1434 1.1 christos /* fpscr_FPRF unchanged */ 1435 1.1 christos } 1436 1.1 christos else { 1437 1.1 christos /* invalid operation exception disabled */ 1438 1.1 christos if (instruction_is_convert_to_64bit) { 1439 1.1 christos error("oopsi"); 1440 1.1 christos } 1441 1.1 christos else if (instruction_is_convert_to_32bit) { 1442 1.1 christos error("oopsi"); 1443 1.1 christos } 1444 1.1 christos else { /* arrith, frsp */ 1445 1.1 christos *frt = select_qnan(fra, frb, frc, 1446 1.1 christos instruction_is_frsp, 1/*generate*/, single); 1447 1.1 christos FPSCR_SET_FR(0); 1448 1.1 christos FPSCR_SET_FI(0); 1449 1.1 christos FPSCR_SET_FPRF(fpscr_rf_quiet_nan); 1450 1.1 christos } 1451 1.1 christos } 1452 1.1 christos 1453 1.1 christos 1454 1.1 christos 1455 1.1 christos 1456 1.1 christos # detect divide by zero 1457 1.1 christos int::function::is_invalid_zero_divide:cpu *processor, unsigned_word cia, uint64_t fra, uint64_t frb, int single 1458 1.1 christos int fail = 0; 1459 1.1 christos if (is_zero (frb)) { 1460 1.1 christos FPSCR_SET_ZX (1); 1461 1.1 christos fail = 1; 1462 1.1 christos } 1463 1.1 christos return fail; 1464 1.1 christos 1465 1.1 christos 1466 1.1 christos 1467 1.1 christos 1468 1.1 christos # handle case of invalid operation 1469 1.1 christos void::function::invalid_zero_divide_operation:cpu *processor, unsigned_word cia, uint64_t *frt, uint64_t fra, uint64_t frb, int single 1470 1.1 christos if (FPSCR & fpscr_ze) { 1471 1.1 christos /* zero-divide exception enabled */ 1472 1.1 christos /* FRT unchaged */ 1473 1.1 christos FPSCR_SET_FR(0); 1474 1.1 christos FPSCR_SET_FI(0); 1475 1.1 christos /* fpscr_FPRF unchanged */ 1476 1.1 christos } 1477 1.1 christos else { 1478 1.1 christos /* zero-divide exception disabled */ 1479 1.1 christos FPSCR_SET_FR(0); 1480 1.1 christos FPSCR_SET_FI(0); 1481 1.1 christos if ((sign (fra) < 0 && sign (frb) < 0) 1482 1.1 christos || (sign (fra) > 0 && sign (frb) > 0)) { 1483 1.1 christos *frt = MASK64 (1, 11); /* 0 : 2047 : 0..0 */ 1484 1.1 christos FPSCR_SET_FPRF(fpscr_rf_pos_infinity); 1485 1.1 christos } 1486 1.1 christos else { 1487 1.1 christos *frt = MASK64 (0, 11); /* 1 : 2047 : 0..0 */ 1488 1.1 christos FPSCR_SET_FPRF(fpscr_rf_neg_infinity); 1489 1.1 christos } 1490 1.1 christos } 1491 1.1 christos 1492 1.1 christos 1493 1.1 christos 1494 1.1 christos 1495 1.1 christos 1496 1.1 christos # 1497 1.1 christos # 0.0.0.0 Illegal instruction used for kernel mode emulation 1498 1.1 christos # 1499 1.1 christos 0.0,6./,11./,16./,21./,31.1:X:::instruction_call 1500 1.1 christos if (!os_emul_instruction_call(processor, cia, real_addr(cia, 1))) 1501 1.1 christos program_interrupt(processor, cia, 1502 1.1 christos illegal_instruction_program_interrupt); 1503 1.1 christos 1504 1.1 christos # 1505 1.1 christos # I.2.4.1 Branch Instructions 1506 1.1 christos # 1507 1.1 christos 0.18,6.LI,30.AA,31.LK:I:::Branch 1508 1.1 christos *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1509 1.1 christos *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1510 1.1 christos *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1511 1.1 christos *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1512 1.1 christos /* option_mpc860c0: 1513 1.1 christos No problem here because this branch is predicted taken (unconditional). */ 1514 1.1 christos if (AA) NIA = IEA(EXTS(LI_0b00)); 1515 1.1 christos else NIA = IEA(CIA + EXTS(LI_0b00)); 1516 1.1 christos if (LK) LR = (spreg)CIA+4; 1517 1.1 christos if (CURRENT_MODEL_ISSUE > 0) 1518 1.1 christos model_branches(cpu_model(processor), 1, -1); 1519 1.1 christos 1520 1.1 christos 0.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:::Branch Conditional 1521 1.1 christos *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1522 1.1 christos *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1523 1.1 christos *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1524 1.1 christos *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1525 1.1 christos int M, ctr_ok, cond_ok, succeed; 1526 1.1 christos if (CURRENT_MODEL_ISSUE > 0 && ! BO{0}) 1527 1.1 christos model_wait_for_cr(cpu_model(processor), BIT32_BI); 1528 1.1 christos if (is_64bit_implementation && is_64bit_mode) M = 0; 1529 1.1 christos else M = 32; 1530 1.1 christos if (!BO{2}) CTR = CTR - 1; 1531 1.1 christos ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != (BO{3})); 1532 1.1 christos cond_ok = BO{0} || ((CR{BI}) == (BO{1})); 1533 1.1 christos if (ctr_ok && cond_ok) { 1534 1.1 christos if (AA) NIA = IEA(EXTS(BD_0b00)); 1535 1.1 christos else NIA = IEA(CIA + EXTS(BD_0b00)); 1536 1.1 christos succeed = 1; 1537 1.1 christos } 1538 1.1 christos else 1539 1.1 christos succeed = 0; 1540 1.1 christos if (LK) LR = (spreg)IEA(CIA + 4); 1541 1.1 christos if (option_mpc860c0 && (!BO{0} || !BO{2}) && !BO{4}) { 1542 1.1 christos /* This branch is predicted as "normal". 1543 1.1 christos If this is a forward branch and it is near the end of a page, 1544 1.1 christos we've detected a problematic branch. */ 1545 1.1 christos if (succeed && NIA > CIA) { 1546 1.1 christos if (MPC860C0_PAGE_SIZE - (CIA & (MPC860C0_PAGE_SIZE-1)) <= option_mpc860c0) 1547 1.1 christos program_interrupt(processor, cia, mpc860c0_instruction_program_interrupt); 1548 1.1 christos } 1549 1.1 christos } 1550 1.1 christos if (CURRENT_MODEL_ISSUE > 0) 1551 1.1 christos model_branches(cpu_model(processor), succeed, BO); 1552 1.1 christos if (! BO{0}) { 1553 1.1 christos int reverse; 1554 1.1 christos if (BO{4}) { /* branch prediction bit set, reverse sense of test */ 1555 1.1 christos reverse = EXTS(BD_0b00) < 0; 1556 1.1 christos } else { /* branch prediction bit not set */ 1557 1.1 christos reverse = EXTS(BD_0b00) >= 0; 1558 1.1 christos } 1559 1.1 christos if (CURRENT_MODEL_ISSUE > 0) 1560 1.1 christos model_branch_predict(cpu_model(processor), reverse ? !succeed : succeed); 1561 1.1 christos } 1562 1.1 christos 1563 1.1 christos 0.19,6.BO,11.BI,16./,21.16,31.LK:XL:::Branch Conditional to Link Register 1564 1.1 christos *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1565 1.1 christos *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1566 1.1 christos *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1567 1.1 christos *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1568 1.1 christos int M, ctr_ok, cond_ok, succeed; 1569 1.1 christos if (is_64bit_implementation && is_64bit_mode) M = 0; 1570 1.1 christos else M = 32; 1571 1.1 christos if (CURRENT_MODEL_ISSUE > 0 && ! BO{0}) 1572 1.1 christos model_wait_for_cr(cpu_model(processor), BIT32_BI); 1573 1.1 christos if (!BO{2}) CTR = CTR - 1; 1574 1.1 christos ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != BO{3}); 1575 1.1 christos cond_ok = BO{0} || (CR{BI} == BO{1}); 1576 1.1 christos if (ctr_ok && cond_ok) { 1577 1.1 christos NIA = IEA(LR_0b00); 1578 1.1 christos succeed = 1; 1579 1.1 christos } 1580 1.1 christos else 1581 1.1 christos succeed = 0; 1582 1.1 christos if (LK) LR = (spreg)IEA(CIA + 4); 1583 1.1 christos if (option_mpc860c0 && (!BO{0} || !BO{2}) && !BO{4}) { 1584 1.1 christos /* This branch is predicted as not-taken. 1585 1.1 christos If this is a forward branch and it is near the end of a page, 1586 1.1 christos we've detected a problematic branch. */ 1587 1.1 christos if (succeed && NIA > CIA) { 1588 1.1 christos if (MPC860C0_PAGE_SIZE - (CIA & (MPC860C0_PAGE_SIZE-1)) <= option_mpc860c0) 1589 1.1 christos program_interrupt(processor, cia, mpc860c0_instruction_program_interrupt); 1590 1.1 christos } 1591 1.1 christos } 1592 1.1 christos if (CURRENT_MODEL_ISSUE > 0) { 1593 1.1 christos model_branches(cpu_model(processor), succeed, BO); 1594 1.1 christos if (! BO{0}) 1595 1.1 christos model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed); 1596 1.1 christos } 1597 1.1 christos 1598 1.1 christos 0.19,6.BO,11.BI,16./,21.528,31.LK:XL:::Branch Conditional to Count Register 1599 1.1 christos *601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1600 1.1 christos *603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1601 1.1 christos *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1602 1.1 christos *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1603 1.1 christos int cond_ok, succeed; 1604 1.1 christos if (CURRENT_MODEL_ISSUE > 0 && ! BO{0}) 1605 1.1 christos model_wait_for_cr(cpu_model(processor), BIT32_BI); 1606 1.1 christos cond_ok = BO{0} || (CR{BI} == BO{1}); 1607 1.1 christos if (cond_ok) { 1608 1.1 christos NIA = IEA(CTR_0b00); 1609 1.1 christos succeed = 1; 1610 1.1 christos } 1611 1.1 christos else 1612 1.1 christos succeed = 0; 1613 1.1 christos if (LK) LR = (spreg)IEA(CIA + 4); 1614 1.1 christos if (option_mpc860c0 && (!BO{0} || !BO{2}) && !BO{4}) { 1615 1.1 christos /* This branch is predicted as not-taken. 1616 1.1 christos If this is a forward branch and it is near the end of a page, 1617 1.1 christos we've detected a problematic branch. */ 1618 1.1 christos if (succeed && NIA > CIA) { 1619 1.1 christos if (MPC860C0_PAGE_SIZE - (CIA & (MPC860C0_PAGE_SIZE-1)) <= option_mpc860c0) 1620 1.1 christos program_interrupt(processor, cia, mpc860c0_instruction_program_interrupt); 1621 1.1 christos } 1622 1.1 christos } 1623 1.1 christos if (CURRENT_MODEL_ISSUE > 0) { 1624 1.1 christos model_branches(cpu_model(processor), succeed, BO); 1625 1.1 christos if (! BO{0}) 1626 1.1 christos model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed); 1627 1.1 christos } 1628 1.1 christos 1629 1.1 christos # 1630 1.1 christos # I.2.4.2 System Call Instruction 1631 1.1 christos # 1632 1.1 christos 0.17,6./,11./,16./,30.1,31./:SC:::System Call 1633 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 1634 1.1 christos *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0 1635 1.1 christos *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0 1636 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 1637 1.1 christos if (CURRENT_MODEL_ISSUE > 0) 1638 1.1 christos model_serialize(MY_INDEX, cpu_model(processor)); 1639 1.1 christos system_call_interrupt(processor, cia); 1640 1.1 christos 1641 1.1 christos # 1642 1.1 christos # I.2.4.3 Condition Register Logical Instructions 1643 1.1 christos # 1644 1.1 christos 0.19,6.BT,11.BA,16.BB,21.257,31./:XL::crand:Condition Register AND 1645 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 1646 1.1 christos *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 1647 1.1 christos *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 1648 1.1 christos *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1649 1.1 christos BLIT32(CR, BT, CR{BA} && CR{BB}); 1650 1.1 christos PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK); 1651 1.1 christos 1652 1.1 christos 0.19,6.BT,11.BA,16.BB,21.449,31./:XL::cror:Condition Register OR 1653 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 1654 1.1 christos *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 1655 1.1 christos *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 1656 1.1 christos *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1657 1.1 christos BLIT32(CR, BT, CR{BA} || CR{BB}); 1658 1.1 christos PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK); 1659 1.1 christos 1660 1.1 christos 0.19,6.BT,11.BA,16.BB,21.193,31./:XL::crxor:Condition Register XOR 1661 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 1662 1.1 christos *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 1663 1.1 christos *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 1664 1.1 christos *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1665 1.1 christos BLIT32(CR, BT, CR{BA} != CR{BB}); 1666 1.1 christos PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK); 1667 1.1 christos 1668 1.1 christos 0.19,6.BT,11.BA,16.BB,21.225,31./:XL::crnand:Condition Register NAND 1669 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 1670 1.1 christos *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 1671 1.1 christos *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 1672 1.1 christos *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1673 1.1 christos BLIT32(CR, BT, !(CR{BA} && CR{BB})); 1674 1.1 christos PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK); 1675 1.1 christos 1676 1.1 christos 0.19,6.BT,11.BA,16.BB,21.33,31./:XL::crnor:Condition Register NOR 1677 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 1678 1.1 christos *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 1679 1.1 christos *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 1680 1.1 christos *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1681 1.1 christos BLIT32(CR, BT, !(CR{BA} || CR{BB})); 1682 1.1 christos PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK); 1683 1.1 christos 1684 1.1 christos 0.19,6.BT,11.BA,16.BB,21.289,31./:XL::creqv:Condition Register Equivalent 1685 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 1686 1.1 christos *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 1687 1.1 christos *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 1688 1.1 christos *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1689 1.1 christos BLIT32(CR, BT, CR{BA} == CR{BB}); 1690 1.1 christos PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK); 1691 1.1 christos 1692 1.1 christos 0.19,6.BT,11.BA,16.BB,21.129,31./:XL::crandc:Condition Register AND with Complement 1693 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 1694 1.1 christos *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 1695 1.1 christos *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 1696 1.1 christos *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1697 1.1 christos BLIT32(CR, BT, CR{BA} && !CR{BB}); 1698 1.1 christos PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK); 1699 1.1 christos 1700 1.1 christos 0.19,6.BT,11.BA,16.BB,21.417,31./:XL::crorc:Condition Register OR with Complement 1701 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 1702 1.1 christos *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 1703 1.1 christos *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 1704 1.1 christos *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1705 1.1 christos BLIT32(CR, BT, CR{BA} || !CR{BB}); 1706 1.1 christos PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK); 1707 1.1 christos 1708 1.1 christos # 1709 1.1 christos # I.2.4.4 Condition Register Field Instruction 1710 1.1 christos # 1711 1.1 christos 0.19,6.BF,9./,11.BFA,14./,16./,21.0,31./:XL:::Move Condition Register Field 1712 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 1713 1.1 christos *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 1714 1.1 christos *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 1715 1.1 christos *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 1716 1.1 christos MBLIT32(CR, 4*BF, 4*BF+3, EXTRACTED32(CR, 4*BFA, 4*BFA+3)); 1717 1.1 christos PPC_INSN_CR(BF_BITMASK, 1 << BFA); 1718 1.1 christos 1719 1.1 christos 1720 1.1 christos # 1721 1.1 christos # I.3.3.2 Fixed-Point Load Instructions 1722 1.1 christos # 1723 1.1 christos 1724 1.1 christos 0.34,6.RT,11.RA,16.D:D:::Load Byte and Zero 1725 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0 1726 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1727 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1728 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1729 1.1 christos unsigned_word b; 1730 1.1 christos unsigned_word EA; 1731 1.1 christos if (RA_is_0) b = 0; 1732 1.1 christos else b = *rA; 1733 1.1 christos EA = b + EXTS(D); 1734 1.1 christos *rT = MEM(unsigned, EA, 1); 1735 1.1 christos PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0); 1736 1.1 christos 1737 1.1 christos 1738 1.1 christos 0.31,6.RT,11.RA,16.RB,21.87,31./:X:::Load Byte and Zero Indexed 1739 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0 1740 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1741 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1742 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1743 1.1 christos unsigned_word b; 1744 1.1 christos unsigned_word EA; 1745 1.1 christos if (RA_is_0) b = 0; 1746 1.1 christos else b = *rA; 1747 1.1 christos EA = b + *rB; 1748 1.1 christos *rT = MEM(unsigned, EA, 1); 1749 1.1 christos PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0); 1750 1.1 christos 1751 1.1 christos 0.35,6.RT,11.RA,16.D:D:::Load Byte and Zero with Update 1752 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0 1753 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1754 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1755 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1756 1.1 christos unsigned_word EA; 1757 1.1 christos if (RA_is_0 || RA == RT) 1758 1.1 christos program_interrupt(processor, cia, 1759 1.1 christos illegal_instruction_program_interrupt); 1760 1.1 christos EA = *rA + EXTS(D); 1761 1.1 christos *rT = MEM(unsigned, EA, 1); 1762 1.1 christos *rA = EA; 1763 1.1 christos PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0); 1764 1.1 christos 1765 1.1 christos 0.31,6.RT,11.RA,16.RB,21.119,31./:X:::Load Byte and Zero with Update Indexed 1766 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0 1767 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1768 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1769 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1770 1.1 christos unsigned_word EA; 1771 1.1 christos if (RA_is_0 || RA == RT) 1772 1.1 christos program_interrupt(processor, cia, 1773 1.1 christos illegal_instruction_program_interrupt); 1774 1.1 christos EA = *rA + *rB; 1775 1.1 christos *rT = MEM(unsigned, EA, 1); 1776 1.1 christos *rA = EA; 1777 1.1 christos PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0); 1778 1.1 christos 1779 1.1 christos 0.40,6.RT,11.RA,16.D:D:::Load Halfword and Zero 1780 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0 1781 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1782 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1783 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1784 1.1 christos unsigned_word b; 1785 1.1 christos unsigned_word EA; 1786 1.1 christos if (RA_is_0) b = 0; 1787 1.1 christos else b = *rA; 1788 1.1 christos EA = b + EXTS(D); 1789 1.1 christos *rT = MEM(unsigned, EA, 2); 1790 1.1 christos PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0); 1791 1.1 christos 1792 1.1 christos 0.31,6.RT,11.RA,16.RB,21.279,31./:X:::Load Halfword and Zero Indexed 1793 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0 1794 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1795 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1796 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1797 1.1 christos unsigned_word b; 1798 1.1 christos unsigned_word EA; 1799 1.1 christos if (RA_is_0) b = 0; 1800 1.1 christos else b = *rA; 1801 1.1 christos EA = b + *rB; 1802 1.1 christos *rT = MEM(unsigned, EA, 2); 1803 1.1 christos PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0); 1804 1.1 christos 1805 1.1 christos 0.41,6.RT,11.RA,16.D:D:::Load Halfword and Zero with Update 1806 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0 1807 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1808 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1809 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1810 1.1 christos unsigned_word EA; 1811 1.1 christos if (RA_is_0 || RA == RT) 1812 1.1 christos program_interrupt(processor, cia, 1813 1.1 christos illegal_instruction_program_interrupt); 1814 1.1 christos EA = *rA + EXTS(D); 1815 1.1 christos *rT = MEM(unsigned, EA, 2); 1816 1.1 christos *rA = EA; 1817 1.1 christos PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0); 1818 1.1 christos 1819 1.1 christos 0.31,6.RT,11.RA,16.RB,21.311,31./:X:::Load Halfword and Zero with Update Indexed 1820 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0 1821 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1822 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1823 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1824 1.1 christos unsigned_word EA; 1825 1.1 christos if (RA_is_0 || RA == RT) 1826 1.1 christos program_interrupt(processor, cia, 1827 1.1 christos illegal_instruction_program_interrupt); 1828 1.1 christos EA = *rA + *rB; 1829 1.1 christos *rT = MEM(unsigned, EA, 2); 1830 1.1 christos *rA = EA; 1831 1.1 christos PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0); 1832 1.1 christos 1833 1.1 christos 0.42,6.RT,11.RA,16.D:D:::Load Halfword Algebraic 1834 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0 1835 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1836 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1837 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1838 1.1 christos unsigned_word b; 1839 1.1 christos unsigned_word EA; 1840 1.1 christos if (RA_is_0) b = 0; 1841 1.1 christos else b = *rA; 1842 1.1 christos EA = b + EXTS(D); 1843 1.1 christos *rT = MEM(signed, EA, 2); 1844 1.1 christos PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0); 1845 1.1 christos 1846 1.1 christos 0.31,6.RT,11.RA,16.RB,21.343,31./:X:::Load Halfword Algebraic Indexed 1847 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0 1848 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1849 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1850 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1851 1.1 christos unsigned_word b; 1852 1.1 christos unsigned_word EA; 1853 1.1 christos if (RA_is_0) b = 0; 1854 1.1 christos else b = *rA; 1855 1.1 christos EA = b + *rB; 1856 1.1 christos *rT = MEM(signed, EA, 2); 1857 1.1 christos PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0); 1858 1.1 christos 1859 1.1 christos 0.43,6.RT,11.RA,16.D:D:::Load Halfword Algebraic with Update 1860 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0 1861 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1862 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1863 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1864 1.1 christos unsigned_word EA; 1865 1.1 christos if (RA_is_0 || RA == RT) 1866 1.1 christos program_interrupt(processor, cia, 1867 1.1 christos illegal_instruction_program_interrupt); 1868 1.1 christos EA = *rA + EXTS(D); 1869 1.1 christos *rT = MEM(signed, EA, 2); 1870 1.1 christos *rA = EA; 1871 1.1 christos PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0); 1872 1.1 christos 1873 1.1 christos 0.31,6.RT,11.RA,16.RB,21.375,31./:X:::Load Halfword Algebraic with Update Indexed 1874 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0 1875 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1876 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1877 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1878 1.1 christos unsigned_word EA; 1879 1.1 christos if (RA_is_0 || RA == RT) 1880 1.1 christos program_interrupt(processor, cia, 1881 1.1 christos illegal_instruction_program_interrupt); 1882 1.1 christos EA = *rA + *rB; 1883 1.1 christos *rT = MEM(signed, EA, 2); 1884 1.1 christos *rA = EA; 1885 1.1 christos PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0); 1886 1.1 christos 1887 1.1 christos 0.32,6.RT,11.RA,16.D:D:::Load Word and Zero 1888 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0 1889 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1890 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1891 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1892 1.1 christos unsigned_word b; 1893 1.1 christos unsigned_word EA; 1894 1.1 christos if (RA_is_0) b = 0; 1895 1.1 christos else b = *rA; 1896 1.1 christos EA = b + EXTS(D); 1897 1.1 christos *rT = MEM(unsigned, EA, 4); 1898 1.1 christos PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0); 1899 1.1 christos 1900 1.1 christos 0.31,6.RT,11.RA,16.RB,21.23,31./:X:::Load Word and Zero Indexed 1901 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0 1902 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1903 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1904 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1905 1.1 christos unsigned_word b; 1906 1.1 christos unsigned_word EA; 1907 1.1 christos if (RA_is_0) b = 0; 1908 1.1 christos else b = *rA; 1909 1.1 christos EA = b + *rB; 1910 1.1 christos *rT = MEM(unsigned, EA, 4); 1911 1.1 christos PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0); 1912 1.1 christos 1913 1.1 christos 0.33,6.RT,11.RA,16.D:D:::Load Word and Zero with Update 1914 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0 1915 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1916 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1917 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1918 1.1 christos unsigned_word EA; 1919 1.1 christos if (RA_is_0 || RA == RT) 1920 1.1 christos program_interrupt(processor, cia, 1921 1.1 christos illegal_instruction_program_interrupt); 1922 1.1 christos EA = *rA + EXTS(D); 1923 1.1 christos *rT = MEM(unsigned, EA, 4); 1924 1.1 christos *rA = EA; 1925 1.1 christos PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK, 0); 1926 1.1 christos 1927 1.1 christos 0.31,6.RT,11.RA,16.RB,21.55,31./:X:::Load Word and Zero with Update Indexed 1928 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 2, 0 1929 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1930 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1931 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 1932 1.1 christos unsigned_word EA; 1933 1.1 christos if (RA_is_0 || RA == RT) 1934 1.1 christos program_interrupt(processor, cia, 1935 1.1 christos illegal_instruction_program_interrupt); 1936 1.1 christos EA = *rA + *rB; 1937 1.1 christos *rT = MEM(unsigned, EA, 4); 1938 1.1 christos *rA = EA; 1939 1.1 christos PPC_INSN_INT(RT_BITMASK | RA_BITMASK, RA_BITMASK | RB_BITMASK, 0); 1940 1.1 christos 1941 1.1 christos 0.58,6.RT,11.RA,16.DS,30.2:DS:64::Load Word Algebraic 1942 1.1 christos # unsigned_word b; 1943 1.1 christos # unsigned_word EA; 1944 1.1 christos # if (RA_is_0) b = 0; 1945 1.1 christos # else b = *rA; 1946 1.1 christos # EA = b + EXTS(DS_0b00); 1947 1.1 christos # *rT = MEM(signed, EA, 4); 1948 1.1 christos 1949 1.1 christos 0.31,6.RT,11.RA,16.RB,21.341,31./:X:64::Load Word Algebraic Indexed 1950 1.1 christos # unsigned_word b; 1951 1.1 christos # unsigned_word EA; 1952 1.1 christos # if (RA_is_0) b = 0; 1953 1.1 christos # else b = *rA; 1954 1.1 christos # EA = b + *rB;; 1955 1.1 christos # *rT = MEM(signed, EA, 4); 1956 1.1 christos 1957 1.1 christos 0.31,6.RT,11.RA,16.RB,21.373,31./:X:64::Load Word Algebraic with Update Indexed 1958 1.1 christos # unsigned_word EA; 1959 1.1 christos # if (RA_is_0 || RA == RT) 1960 1.1 christos # program_interrupt(processor, cia 1961 1.1 christos # illegal_instruction_program_interrupt); 1962 1.1 christos # EA = *rA + *rB; 1963 1.1 christos # *rT = MEM(signed, EA, 4); 1964 1.1 christos # *rA = EA; 1965 1.1 christos 1966 1.1 christos 0.58,6.RT,11.RA,16.DS,30.0:DS:64::Load Doubleword 1967 1.1 christos # unsigned_word b; 1968 1.1 christos # unsigned_word EA; 1969 1.1 christos # if (RA_is_0) b = 0; 1970 1.1 christos # else b = *rA; 1971 1.1 christos # EA = b + EXTS(DS_0b00); 1972 1.1 christos # *rT = MEM(unsigned, EA, 8); 1973 1.1 christos 1974 1.1 christos 0.31,6.RT,11.RA,16.RB,21.21,31./:X:64::Load Doubleword Indexed 1975 1.1 christos # unsigned_word b; 1976 1.1 christos # unsigned_word EA; 1977 1.1 christos # if (RA_is_0) b = 0; 1978 1.1 christos # else b = *rA; 1979 1.1 christos # EA = b + *rB; 1980 1.1 christos # *rT = MEM(unsigned, EA, 8); 1981 1.1 christos 1982 1.1 christos 0.58,6.RT,11.RA,16.DS,30.1:DS:64::Load Doubleword with Update 1983 1.1 christos # unsigned_word EA; 1984 1.1 christos # if (RA_is_0 || RA == RT) 1985 1.1 christos # program_interrupt(processor, cia 1986 1.1 christos # illegal_instruction_program_interrupt); 1987 1.1 christos # EA = *rA + EXTS(DS_0b00); 1988 1.1 christos # *rT = MEM(unsigned, EA, 8); 1989 1.1 christos # *rA = EA; 1990 1.1 christos 1991 1.1 christos 0.31,6.RT,11.RA,16.RB,21.53,31./:DS:64::Load Doubleword with Update Indexed 1992 1.1 christos # unsigned_word EA; 1993 1.1 christos # if (RA_is_0 || RA == RT) 1994 1.1 christos # program_interrupt(processor, cia 1995 1.1 christos # illegal_instruction_program_interrupt); 1996 1.1 christos # EA = *rA + *rB; 1997 1.1 christos # *rT = MEM(unsigned, EA, 8); 1998 1.1 christos # *rA = EA; 1999 1.1 christos 2000 1.1 christos 2001 1.1 christos 2002 1.1 christos # 2003 1.1 christos # I.3.3.3 Fixed-Point Store Instructions 2004 1.1 christos # 2005 1.1 christos 2006 1.1 christos 0.38,6.RS,11.RA,16.D:D:::Store Byte 2007 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2008 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2009 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2010 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 2011 1.1 christos unsigned_word b; 2012 1.1 christos unsigned_word EA; 2013 1.1 christos if (RA_is_0) b = 0; 2014 1.1 christos else b = *rA; 2015 1.1 christos EA = b + EXTS(D); 2016 1.1 christos STORE(EA, 1, *rS); 2017 1.1 christos PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0); 2018 1.1 christos 2019 1.1 christos 0.31,6.RS,11.RA,16.RB,21.215,31./:X:::Store Byte Indexed 2020 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2021 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2022 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2023 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 2024 1.1 christos unsigned_word b; 2025 1.1 christos unsigned_word EA; 2026 1.1 christos if (RA_is_0) b = 0; 2027 1.1 christos else b = *rA; 2028 1.1 christos EA = b + *rB; 2029 1.1 christos STORE(EA, 1, *rS); 2030 1.1 christos PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0); 2031 1.1 christos 2032 1.1 christos 0.39,6.RS,11.RA,16.D:D:::Store Byte with Update 2033 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2034 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2035 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2036 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 2037 1.1 christos unsigned_word EA; 2038 1.1 christos if (RA_is_0) 2039 1.1 christos program_interrupt(processor, cia, 2040 1.1 christos illegal_instruction_program_interrupt); 2041 1.1 christos EA = *rA + EXTS(D); 2042 1.1 christos STORE(EA, 1, *rS); 2043 1.1 christos *rA = EA; 2044 1.1 christos PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0); 2045 1.1 christos 2046 1.1 christos 0.31,6.RS,11.RA,16.RB,21.247,31./:X:::Store Byte with Update Indexed 2047 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2048 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2049 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2050 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 2051 1.1 christos unsigned_word EA; 2052 1.1 christos if (RA_is_0) 2053 1.1 christos program_interrupt(processor, cia, 2054 1.1 christos illegal_instruction_program_interrupt); 2055 1.1 christos EA = *rA + *rB; 2056 1.1 christos STORE(EA, 1, *rS); 2057 1.1 christos *rA = EA; 2058 1.1 christos PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0); 2059 1.1 christos 2060 1.1 christos 0.44,6.RS,11.RA,16.D:D:::Store Half Word 2061 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2062 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2063 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2064 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 2065 1.1 christos unsigned_word b; 2066 1.1 christos unsigned_word EA; 2067 1.1 christos if (RA_is_0) b = 0; 2068 1.1 christos else b = *rA; 2069 1.1 christos EA = b + EXTS(D); 2070 1.1 christos STORE(EA, 2, *rS); 2071 1.1 christos PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0); 2072 1.1 christos 2073 1.1 christos 0.31,6.RS,11.RA,16.RB,21.407,31./:X:::Store Half Word Indexed 2074 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2075 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2076 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2077 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 2078 1.1 christos unsigned_word b; 2079 1.1 christos unsigned_word EA; 2080 1.1 christos if (RA_is_0) b = 0; 2081 1.1 christos else b = *rA; 2082 1.1 christos EA = b + *rB; 2083 1.1 christos STORE(EA, 2, *rS); 2084 1.1 christos PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0); 2085 1.1 christos 2086 1.1 christos 0.45,6.RS,11.RA,16.D:D:::Store Half Word with Update 2087 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2088 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2089 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2090 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 2091 1.1 christos unsigned_word EA; 2092 1.1 christos if (RA_is_0) 2093 1.1 christos program_interrupt(processor, cia, 2094 1.1 christos illegal_instruction_program_interrupt); 2095 1.1 christos EA = *rA + EXTS(D); 2096 1.1 christos STORE(EA, 2, *rS); 2097 1.1 christos *rA = EA; 2098 1.1 christos PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0); 2099 1.1 christos 2100 1.1 christos 0.31,6.RS,11.RA,16.RB,21.439,31./:X:::Store Half Word with Update Indexed 2101 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2102 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2103 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2104 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 2105 1.1 christos unsigned_word EA; 2106 1.1 christos if (RA_is_0) 2107 1.1 christos program_interrupt(processor, cia, 2108 1.1 christos illegal_instruction_program_interrupt); 2109 1.1 christos EA = *rA + *rB; 2110 1.1 christos STORE(EA, 2, *rS); 2111 1.1 christos *rA = EA; 2112 1.1 christos PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0); 2113 1.1 christos 2114 1.1 christos 0.36,6.RS,11.RA,16.D:D:::Store Word 2115 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2116 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2117 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2118 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 2119 1.1 christos unsigned_word b; 2120 1.1 christos unsigned_word EA; 2121 1.1 christos if (RA_is_0) b = 0; 2122 1.1 christos else b = *rA; 2123 1.1 christos EA = b + EXTS(D); 2124 1.1 christos STORE(EA, 4, *rS); 2125 1.1 christos PPC_INSN_INT(0, (RA_BITMASK & ~1) | RS_BITMASK, 0); 2126 1.1 christos 2127 1.1 christos 0.31,6.RS,11.RA,16.RB,21.151,31./:X:::Store Word Indexed 2128 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2129 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2130 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2131 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 2132 1.1 christos unsigned_word b; 2133 1.1 christos unsigned_word EA; 2134 1.1 christos if (RA_is_0) b = 0; 2135 1.1 christos else b = *rA; 2136 1.1 christos EA = b + *rB; 2137 1.1 christos STORE(EA, 4, *rS); 2138 1.1 christos PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0); 2139 1.1 christos 2140 1.1 christos 0.37,6.RS,11.RA,16.D:D:::Store Word with Update 2141 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2142 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2143 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2144 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 2145 1.1 christos unsigned_word EA; 2146 1.1 christos if (RA_is_0) 2147 1.1 christos program_interrupt(processor, cia, 2148 1.1 christos illegal_instruction_program_interrupt); 2149 1.1 christos EA = *rA + EXTS(D); 2150 1.1 christos STORE(EA, 4, *rS); 2151 1.1 christos *rA = EA; 2152 1.1 christos PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RS_BITMASK, 0); 2153 1.1 christos 2154 1.1 christos 0.31,6.RS,11.RA,16.RB,21.183,31./:X:::Store Word with Update Indexed 2155 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2156 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2157 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2158 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 2159 1.1 christos unsigned_word EA; 2160 1.1 christos if (RA_is_0) 2161 1.1 christos program_interrupt(processor, cia, 2162 1.1 christos illegal_instruction_program_interrupt); 2163 1.1 christos EA = *rA + *rB; 2164 1.1 christos STORE(EA, 4, *rS); 2165 1.1 christos *rA = EA; 2166 1.1 christos PPC_INSN_INT(RA_BITMASK, RA_BITMASK | RB_BITMASK | RS_BITMASK, 0); 2167 1.1 christos 2168 1.1 christos 0.62,6.RS,11.RA,16.DS,30.0:DS:64::Store Doubleword 2169 1.1 christos # unsigned_word b; 2170 1.1 christos # unsigned_word EA; 2171 1.1 christos # if (RA_is_0) b = 0; 2172 1.1 christos # else b = *rA; 2173 1.1 christos # EA = b + EXTS(DS_0b00); 2174 1.1 christos # STORE(EA, 8, *rS); 2175 1.1 christos 0.31,6.RS,11.RA,16.RB,21.149,31./:X:64::Store Doubleword Indexed 2176 1.1 christos # unsigned_word b; 2177 1.1 christos # unsigned_word EA; 2178 1.1 christos # if (RA_is_0) b = 0; 2179 1.1 christos # else b = *rA; 2180 1.1 christos # EA = b + *rB; 2181 1.1 christos # STORE(EA, 8, *rS); 2182 1.1 christos 0.62,6.RS,11.RA,16.DS,30.1:DS:64::Store Doubleword with Update 2183 1.1 christos # unsigned_word EA; 2184 1.1 christos # if (RA_is_0) 2185 1.1 christos # program_interrupt(processor, cia 2186 1.1 christos # illegal_instruction_program_interrupt); 2187 1.1 christos # EA = *rA + EXTS(DS_0b00); 2188 1.1 christos # STORE(EA, 8, *rS); 2189 1.1 christos # *rA = EA; 2190 1.1 christos 0.31,6.RS,11.RA,16.RB,21.181,31./:X:64::Store Doubleword with Update Indexed 2191 1.1 christos # unsigned_word EA; 2192 1.1 christos # if (RA_is_0) 2193 1.1 christos # program_interrupt(processor, cia 2194 1.1 christos # illegal_instruction_program_interrupt); 2195 1.1 christos # EA = *rA + *rB; 2196 1.1 christos # STORE(EA, 8, *rS); 2197 1.1 christos # *rA = EA; 2198 1.1 christos 2199 1.1 christos 2200 1.1 christos # 2201 1.1 christos # I.3.3.4 Fixed-Point Load and Store with Byte Reversal Instructions 2202 1.1 christos # 2203 1.1 christos 2204 1.1 christos 0.31,6.RT,11.RA,16.RB,21.790,31./:X:::Load Halfword Byte-Reverse Indexed 2205 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2206 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2207 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2208 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 2209 1.1 christos unsigned_word b; 2210 1.1 christos unsigned_word EA; 2211 1.1 christos if (RA_is_0) b = 0; 2212 1.1 christos else b = *rA; 2213 1.1 christos EA = b + *rB; 2214 1.1 christos *rT = SWAP_2(MEM(unsigned, EA, 2)); 2215 1.1 christos PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0); 2216 1.1 christos 2217 1.1 christos 0.31,6.RT,11.RA,16.RB,21.534,31./:X:::Load Word Byte-Reverse Indexed 2218 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2219 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2220 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2221 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 2222 1.1 christos unsigned_word b; 2223 1.1 christos unsigned_word EA; 2224 1.1 christos if (RA_is_0) b = 0; 2225 1.1 christos else b = *rA; 2226 1.1 christos EA = b + *rB; 2227 1.1 christos *rT = SWAP_4(MEM(unsigned, EA, 4)); 2228 1.1 christos PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0); 2229 1.1 christos 2230 1.1 christos 0.31,6.RS,11.RA,16.RB,21.918,31./:X:::Store Half Word Byte-Reversed Indexed 2231 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2232 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2233 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2234 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 2235 1.1 christos unsigned_word b; 2236 1.1 christos unsigned_word EA; 2237 1.1 christos if (RA_is_0) b = 0; 2238 1.1 christos else b = *rA; 2239 1.1 christos EA = b + *rB; 2240 1.1 christos STORE(EA, 2, SWAP_2(*rS)); 2241 1.1 christos PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0); 2242 1.1 christos 2243 1.1 christos 0.31,6.RS,11.RA,16.RB,21.662,31./:X:::Store Word Byte-Reversed Indexed 2244 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2245 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2246 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 2247 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 2248 1.1 christos unsigned_word b; 2249 1.1 christos unsigned_word EA; 2250 1.1 christos if (RA_is_0) b = 0; 2251 1.1 christos else b = *rA; 2252 1.1 christos EA = b + *rB; 2253 1.1 christos STORE(EA, 4, SWAP_4(*rS)); 2254 1.1 christos PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 0); 2255 1.1 christos 2256 1.1 christos 2257 1.1 christos # 2258 1.1 christos # I.3.3.5 Fixed-Point Load and Store Multiple Instrctions 2259 1.1 christos # 2260 1.1 christos 2261 1.1 christos 0.46,6.RT,11.RA,16.D:D:::Load Multiple Word 2262 1.1 christos unsigned_word EA; 2263 1.1 christos unsigned_word b; 2264 1.1 christos int r; 2265 1.1 christos if (RA_is_0) b = 0; 2266 1.1 christos else b = *rA; 2267 1.1 christos EA = b + EXTS(D); 2268 1.1 christos r = RT; 2269 1.1 christos if (RA >= r) 2270 1.1 christos program_interrupt(processor, cia, 2271 1.1 christos illegal_instruction_program_interrupt); 2272 1.1 christos if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT || (EA % 4 != 0)) 2273 1.1 christos alignment_interrupt(processor, cia, EA); 2274 1.1 christos while (r <= 31) { 2275 1.1 christos GPR(r) = MEM(unsigned, EA, 4); 2276 1.1 christos r = r + 1; 2277 1.1 christos EA = EA + 4; 2278 1.1 christos } 2279 1.1 christos 2280 1.1 christos 0.47,6.RS,11.RA,16.D:D:::Store Multiple Word 2281 1.1 christos unsigned_word EA; 2282 1.1 christos unsigned_word b; 2283 1.1 christos int r; 2284 1.1 christos if (RA_is_0) b = 0; 2285 1.1 christos else b = *rA; 2286 1.1 christos EA = b + EXTS(D); 2287 1.1 christos if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT 2288 1.1 christos || (EA % 4 != 0)) 2289 1.1 christos alignment_interrupt(processor, cia, EA); 2290 1.1 christos r = RS; 2291 1.1 christos while (r <= 31) { 2292 1.1 christos STORE(EA, 4, GPR(r)); 2293 1.1 christos r = r + 1; 2294 1.1 christos EA = EA + 4; 2295 1.1 christos } 2296 1.1 christos 2297 1.1 christos 2298 1.1 christos # 2299 1.1 christos # I.3.3.6 Fixed-Point Move Assist Instructions 2300 1.1 christos # 2301 1.1 christos 2302 1.1 christos 0.31,6.RT,11.RA,16.NB,21.597,31./:X:::Load String Word Immediate 2303 1.1 christos unsigned_word EA; 2304 1.1 christos int n; 2305 1.1 christos int r; 2306 1.1 christos int i; 2307 1.1 christos int nr; 2308 1.1 christos if (RA_is_0) EA = 0; 2309 1.1 christos else EA = *rA; 2310 1.1 christos if (NB == 0) n = 32; 2311 1.1 christos else n = NB; 2312 1.1 christos r = RT - 1; 2313 1.1 christos i = 32; 2314 1.1 christos nr = (n + 3) / 4; 2315 1.1 christos if ((RT + nr >= 32) 2316 1.1 christos ? (RA >= RT || RA < (RT + nr) % 32) 2317 1.1 christos : (RA >= RT && RA < RT + nr)) 2318 1.1 christos program_interrupt(processor, cia, 2319 1.1 christos illegal_instruction_program_interrupt); 2320 1.1 christos if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT) 2321 1.1 christos alignment_interrupt(processor, cia, EA); 2322 1.1 christos while (n > 0) { 2323 1.1 christos if (i == 32) { 2324 1.1 christos r = (r + 1) % 32; 2325 1.1 christos GPR(r) = 0; 2326 1.1 christos } 2327 1.1 christos GPR(r) |= INSERTED(MEM(unsigned, EA, 1), i, i+7); 2328 1.1 christos i = i + 8; 2329 1.1 christos if (i == 64) i = 32; 2330 1.1 christos EA = EA + 1; 2331 1.1 christos n = n - 1; 2332 1.1 christos } 2333 1.1 christos 2334 1.1 christos 0.31,6.RT,11.RA,16.RB,21.533,31./:X:::Load String Word Indexed 2335 1.1 christos unsigned_word EA; 2336 1.1 christos unsigned_word b; 2337 1.1 christos int n; 2338 1.1 christos int r; 2339 1.1 christos int i; 2340 1.1 christos int nr; 2341 1.1 christos if (RA_is_0) b = 0; 2342 1.1 christos else b = *rA; 2343 1.1 christos EA = b + *rB; 2344 1.1 christos n = EXTRACTED32(XER, 25, 31); 2345 1.1 christos r = RT - 1; 2346 1.1 christos i = 32; 2347 1.1 christos nr = (n + 3) / 4; 2348 1.1 christos if (((RT + nr >= 32) 2349 1.1 christos ? ((RA >= RT || RA < (RT + nr) % 32) 2350 1.1 christos || (RB >= RT || RB < (RT + nr) % 32)) 2351 1.1 christos : ((RA >= RT && RA < RT + nr) 2352 1.1 christos || (RB >= RT && RB < RT + nr))) 2353 1.1 christos || (RT == RA || RT == RB)) 2354 1.1 christos program_interrupt(processor, cia, 2355 1.1 christos illegal_instruction_program_interrupt); 2356 1.1 christos if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT) 2357 1.1 christos alignment_interrupt(processor, cia, EA); 2358 1.1 christos while (n > 0) { 2359 1.1 christos if (i == 32) { 2360 1.1 christos r = (r + 1) % 32; 2361 1.1 christos GPR(r) = 0; 2362 1.1 christos } 2363 1.1 christos GPR(r) |= INSERTED(MEM(unsigned, EA, 1), i, i+7); 2364 1.1 christos i = i + 8; 2365 1.1 christos if (i == 64) i = 32; 2366 1.1 christos EA = EA + 1; 2367 1.1 christos n = n - 1; 2368 1.1 christos } 2369 1.1 christos 2370 1.1 christos 0.31,6.RS,11.RA,16.NB,21.725,31./:X:::Store String Word Immedate 2371 1.1 christos unsigned_word EA; 2372 1.1 christos int n; 2373 1.1 christos int r; 2374 1.1 christos int i; 2375 1.1 christos if (RA_is_0) EA = 0; 2376 1.1 christos else EA = *rA; 2377 1.1 christos if (NB == 0) n = 32; 2378 1.1 christos else n = NB; 2379 1.1 christos r = RS - 1; 2380 1.1 christos i = 32; 2381 1.1 christos if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT) 2382 1.1 christos alignment_interrupt(processor, cia, EA); 2383 1.1 christos while (n > 0) { 2384 1.1 christos if (i == 32) r = (r + 1) % 32; 2385 1.1 christos STORE(EA, 1, EXTRACTED(GPR(r), i, i+7)); 2386 1.1 christos i = i + 8; 2387 1.1 christos if (i == 64) i = 32; 2388 1.1 christos EA = EA + 1; 2389 1.1 christos n = n - 1; 2390 1.1 christos } 2391 1.1 christos 2392 1.1 christos 0.31,6.RS,11.RA,16.RB,21.661,31./:X:::Store String Word Indexed 2393 1.1 christos unsigned_word EA; 2394 1.1 christos unsigned_word b; 2395 1.1 christos int n; 2396 1.1 christos int r; 2397 1.1 christos int i; 2398 1.1 christos if (RA_is_0) b = 0; 2399 1.1 christos else b = *rA; 2400 1.1 christos EA = b + *rB; 2401 1.1 christos if (CURRENT_ALIGNMENT == STRICT_ALIGNMENT) 2402 1.1 christos alignment_interrupt(processor, cia, EA); 2403 1.1 christos n = EXTRACTED32(XER, 25, 31); 2404 1.1 christos r = RS - 1; 2405 1.1 christos i = 32; 2406 1.1 christos while (n > 0) { 2407 1.1 christos if (i == 32) r = (r + 1) % 32; 2408 1.1 christos STORE(EA, 1, EXTRACTED(GPR(r), i, i+7)); 2409 1.1 christos i = i + 8; 2410 1.1 christos if (i == 64) i = 32; 2411 1.1 christos EA = EA + 1; 2412 1.1 christos n = n - 1; 2413 1.1 christos } 2414 1.1 christos 2415 1.1 christos 2416 1.1 christos # 2417 1.1 christos # I.3.3.7 Storage Synchronization Instructions 2418 1.1 christos # 2419 1.1 christos # HACK: Rather than monitor addresses looking for a reason 2420 1.1 christos # to cancel a reservation. This code instead keeps 2421 1.1 christos # a copy of the data read from memory. Before performing 2422 1.1 christos # a store, the memory area is checked to see if it has 2423 1.1 christos # been changed. 2424 1.1 christos 0.31,6.RT,11.RA,16.RB,21.20,31./:X:::Load Word And Reserve Indexed 2425 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0 2426 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0 2427 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_IU, 1, 2, 0 2428 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 2429 1.1 christos unsigned_word b; 2430 1.1 christos unsigned_word EA; 2431 1.1 christos if (RA_is_0) b = 0; 2432 1.1 christos else b = *rA; 2433 1.1 christos EA = b + *rB; 2434 1.1 christos RESERVE = 1; 2435 1.1 christos RESERVE_ADDR = real_addr(EA, 1/*is-read?*/); 2436 1.1 christos RESERVE_DATA = MEM(unsigned, EA, 4); 2437 1.1 christos *rT = RESERVE_DATA; 2438 1.1 christos PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0); 2439 1.1 christos 2440 1.1 christos 0.31,6.RT,11.RA,16.RB,21.84,31./:X:64::Load Doubleword And Reserve Indexed 2441 1.1 christos unsigned_word b; 2442 1.1 christos unsigned_word EA; 2443 1.1 christos if (RA_is_0) b = 0; 2444 1.1 christos else b = *rA; 2445 1.1 christos EA = b + *rB; 2446 1.1 christos RESERVE = 1; 2447 1.1 christos RESERVE_ADDR = real_addr(EA, 1/*is-read?*/); 2448 1.1 christos RESERVE_DATA = MEM(unsigned, EA, 8); 2449 1.1 christos *rT = RESERVE_DATA; 2450 1.1 christos PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0); 2451 1.1 christos 2452 1.1 christos 0.31,6.RS,11.RA,16.RB,21.150,31.1:X:::Store Word Conditional Indexed 2453 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2454 1.1 christos *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0 2455 1.1 christos *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 8, 8, 0 2456 1.1 christos *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 3, 0 2457 1.1 christos unsigned_word b; 2458 1.1 christos unsigned_word EA; 2459 1.1 christos if (RA_is_0) b = 0; 2460 1.1 christos else b = *rA; 2461 1.1 christos EA = b + *rB; 2462 1.1 christos if (RESERVE) { 2463 1.1 christos if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/) 2464 1.1 christos && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 4)) { 2465 1.1 christos STORE(EA, 4, *rS); 2466 1.1 christos CR_SET_XER_SO(0, cr_i_zero); 2467 1.1 christos } 2468 1.1 christos else { 2469 1.1 christos /* ment to randomly to store, we never do! */ 2470 1.1 christos CR_SET_XER_SO(0, 0); 2471 1.1 christos } 2472 1.1 christos RESERVE = 0; 2473 1.1 christos } 2474 1.1 christos else { 2475 1.1 christos CR_SET_XER_SO(0, 0); 2476 1.1 christos } 2477 1.1 christos PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/); 2478 1.1 christos 2479 1.1 christos 0.31,6.RS,11.RA,16.RB,21.214,31.1:X:64::Store Doubleword Conditional Indexed 2480 1.1 christos unsigned_word b; 2481 1.1 christos unsigned_word EA; 2482 1.1 christos if (RA_is_0) b = 0; 2483 1.1 christos else b = *rA; 2484 1.1 christos EA = b + *rB; 2485 1.1 christos if (RESERVE) { 2486 1.1 christos if (RESERVE_ADDR == real_addr(EA, 0/*is-read?*/) 2487 1.1 christos && /*HACK*/ RESERVE_DATA == MEM(unsigned, EA, 8)) { 2488 1.1 christos STORE(EA, 8, *rS); 2489 1.1 christos CR_SET_XER_SO(0, cr_i_zero); 2490 1.1 christos } 2491 1.1 christos else { 2492 1.1 christos /* ment to randomly to store, we never do */ 2493 1.1 christos CR_SET_XER_SO(0, 0); 2494 1.1 christos } 2495 1.1 christos RESERVE = 0; 2496 1.1 christos } 2497 1.1 christos else { 2498 1.1 christos CR_SET_XER_SO(0, 0); 2499 1.1 christos } 2500 1.1 christos PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK | RS_BITMASK, 1/*Rc*/); 2501 1.1 christos 2502 1.1 christos 0.31,6./,9.L,11./,16./,21.598,31./:X::sync:Synchronize 2503 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2504 1.1 christos *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 2505 1.1 christos *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 2506 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0 2507 1.1 christos /* do nothing */ 2508 1.1 christos 2509 1.1 christos 2510 1.1 christos # 2511 1.1 christos # I.3.3.9 Fixed-Point Arithmetic Instructions 2512 1.1 christos # 2513 1.1 christos 2514 1.1 christos 0.14,6.RT,11.RA,16.SI:D:::Add Immediate 2515 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2516 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2517 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0 2518 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2519 1.1 christos if (RA_is_0) *rT = EXTS(SI); 2520 1.1 christos else *rT = *rA + EXTS(SI); 2521 1.1 christos ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rT, (long)*rT)); 2522 1.1 christos PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0); 2523 1.1 christos 2524 1.1 christos 0.15,6.RT,11.RA,16.SI:D:::Add Immediate Shifted 2525 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2526 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2527 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0 2528 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2529 1.1 christos if (RA_is_0) *rT = EXTS(SI) << 16; 2530 1.1 christos else *rT = *rA + (EXTS(SI) << 16); 2531 1.1 christos ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rT, (long)*rT)); 2532 1.1 christos PPC_INSN_INT(RT_BITMASK, (RA_BITMASK & ~1), 0); 2533 1.1 christos 2534 1.1 christos 0.31,6.RT,11.RA,16.RB,21.OE,22.266,31.Rc:XO:::Add 2535 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2536 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2537 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0 2538 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2539 1.1 christos ALU_BEGIN(*rA); 2540 1.1 christos ALU_ADD(*rB); 2541 1.1 christos ALU_END(*rT, 0/*CA*/, OE, Rc); 2542 1.1 christos PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc); 2543 1.1 christos 2544 1.1 christos 0.31,6.RT,11.RA,16.RB,21.OE,22.40,31.Rc:XO:::Subtract From 2545 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2546 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2547 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2548 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2549 1.1 christos ALU_BEGIN(*rA); 2550 1.1 christos ALU_NOT; 2551 1.1 christos ALU_ADD(*rB); 2552 1.1 christos ALU_ADD(1); 2553 1.1 christos ALU_END(*rT, 0/*CA*/, OE, Rc); 2554 1.1 christos PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc); 2555 1.1 christos 2556 1.1 christos 0.12,6.RT,11.RA,16.SI:D:::Add Immediate Carrying 2557 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2558 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2559 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2560 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2561 1.1 christos ALU_BEGIN(*rA); 2562 1.1 christos ALU_ADD(EXTS(SI)); 2563 1.1 christos ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/); 2564 1.1 christos PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/); 2565 1.1 christos 2566 1.1 christos 0.13,6.RT,11.RA,16.SI:D:::Add Immediate Carrying and Record 2567 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2568 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2569 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2570 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2571 1.1 christos ALU_BEGIN(*rA); 2572 1.1 christos ALU_ADD(EXTS(SI)); 2573 1.1 christos ALU_END(*rT, 1/*CA*/, 0/*OE*/, 1/*Rc*/); 2574 1.1 christos PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 1/*Rc*/); 2575 1.1 christos 2576 1.1 christos 0.8,6.RT,11.RA,16.SI:D:::Subtract From Immediate Carrying 2577 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2578 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2579 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2580 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2581 1.1 christos ALU_BEGIN(*rA); 2582 1.1 christos ALU_NOT; 2583 1.1 christos ALU_ADD(EXTS(SI)); 2584 1.1 christos ALU_ADD(1); 2585 1.1 christos ALU_END(*rT, 1/*CA*/, 0/*OE*/, 0/*Rc*/); 2586 1.1 christos PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/); 2587 1.1 christos 2588 1.1 christos 0.31,6.RT,11.RA,16.RB,21.OE,22.10,31.Rc:XO:::Add Carrying 2589 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2590 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2591 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2592 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2593 1.1 christos ALU_BEGIN(*rA); 2594 1.1 christos ALU_ADD(*rB); 2595 1.1 christos ALU_END(*rT, 1/*CA*/, OE, Rc); 2596 1.1 christos PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc); 2597 1.1 christos 2598 1.1 christos 0.31,6.RT,11.RA,16.RB,21.OE,22.8,31.Rc:XO:::Subtract From Carrying 2599 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2600 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2601 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2602 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2603 1.1 christos /* RT <- ~RA + RB + 1 === RT <- RB - RA */ 2604 1.1 christos ALU_BEGIN(*rA); 2605 1.1 christos ALU_NOT; 2606 1.1 christos ALU_ADD(*rB); 2607 1.1 christos ALU_ADD(1); 2608 1.1 christos ALU_END(*rT, 1/*CA*/, OE, Rc); 2609 1.1 christos PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc); 2610 1.1 christos 2611 1.1 christos 0.31,6.RT,11.RA,16.RB,21.OE,22.138,31.Rc:XO:::Add Extended 2612 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2613 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2614 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2615 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2616 1.1 christos ALU_BEGIN(*rA); 2617 1.1 christos ALU_ADD(*rB); 2618 1.1 christos ALU_ADD_CA; 2619 1.1 christos ALU_END(*rT, 1/*CA*/, OE, Rc); 2620 1.1 christos PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc); 2621 1.1 christos 2622 1.1 christos 0.31,6.RT,11.RA,16.RB,21.OE,22.136,31.Rc:XO:::Subtract From Extended 2623 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2624 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2625 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2626 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2627 1.1 christos ALU_BEGIN(*rA); 2628 1.1 christos ALU_NOT; 2629 1.1 christos ALU_ADD(*rB); 2630 1.1 christos ALU_ADD_CA; 2631 1.1 christos ALU_END(*rT, 1/*CA*/, OE, Rc); 2632 1.1 christos PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc); 2633 1.1 christos 2634 1.1 christos 0.31,6.RT,11.RA,16./,21.OE,22.234,31.Rc:XO:::Add to Minus One Extended 2635 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2636 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2637 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2638 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2639 1.1 christos ALU_BEGIN(*rA); 2640 1.1 christos ALU_ADD_CA; 2641 1.1 christos ALU_ADD(-1); 2642 1.1 christos ALU_END(*rT, 1/*CA*/, OE, Rc); 2643 1.1 christos PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc); 2644 1.1 christos 2645 1.1 christos 0.31,6.RT,11.RA,16./,21.OE,22.232,31.Rc:XO:::Subtract From Minus One Extended 2646 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2647 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2648 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2649 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2650 1.1 christos ALU_BEGIN(*rA); 2651 1.1 christos ALU_NOT; 2652 1.1 christos ALU_ADD_CA; 2653 1.1 christos ALU_ADD(-1); 2654 1.1 christos ALU_END(*rT, 1/*CA*/, OE, Rc); 2655 1.1 christos PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc); 2656 1.1 christos 2657 1.1 christos 0.31,6.RT,11.RA,16./,21.OE,22.202,31.Rc:XO::addze:Add to Zero Extended 2658 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2659 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2660 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2661 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2662 1.1 christos ALU_BEGIN(*rA); 2663 1.1 christos ALU_ADD_CA; 2664 1.1 christos ALU_END(*rT, 1/*CA*/, OE, Rc); 2665 1.1 christos PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc); 2666 1.1 christos 2667 1.1 christos 0.31,6.RT,11.RA,16./,21.OE,22.200,31.Rc:XO:::Subtract from Zero Extended 2668 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2669 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2670 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2671 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2672 1.1 christos ALU_BEGIN(*rA); 2673 1.1 christos ALU_NOT; 2674 1.1 christos ALU_ADD_CA; 2675 1.1 christos ALU_END(*rT, 1/*CA*/, OE, Rc); 2676 1.1 christos PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc); 2677 1.1 christos 2678 1.1 christos 0.31,6.RT,11.RA,16./,21.OE,22.104,31.Rc:XO:::Negate 2679 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2680 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2681 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2682 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2683 1.1 christos ALU_BEGIN(*rA); 2684 1.1 christos ALU_NOT; 2685 1.1 christos ALU_ADD(1); 2686 1.1 christos ALU_END(*rT,0/*CA*/,OE,Rc); 2687 1.1 christos PPC_INSN_INT(RT_BITMASK, RA_BITMASK, Rc); 2688 1.1 christos 2689 1.1 christos 0.7,6.RT,11.RA,16.SI:D::mulli:Multiply Low Immediate 2690 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0 2691 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0 2692 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0 2693 1.1 christos *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0 2694 1.1 christos signed_word prod = *rA * EXTS(SI); 2695 1.1 christos *rT = prod; 2696 1.1 christos PPC_INSN_INT(RT_BITMASK, RA_BITMASK, 0/*Rc*/); 2697 1.1 christos 2698 1.1 christos 0.31,6.RT,11.RA,16.RB,21.OE,22.233,31.Rc:D:64::Multiply Low Doubleword 2699 1.1 christos 2700 1.1 christos 0.31,6.RT,11.RA,16.RB,21.OE,22.235,31.Rc:XO::mullw:Multiply Low Word 2701 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0 2702 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0 2703 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0 2704 1.1 christos *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0 2705 1.1 christos int64_t a = (int32_t)(*rA); 2706 1.1 christos int64_t b = (int32_t)(*rB); 2707 1.1 christos int64_t prod = a * b; 2708 1.1 christos signed_word t = prod; 2709 1.1 christos *rT = *rA * *rB; 2710 1.1 christos if (t != prod && OE) 2711 1.1 christos XER |= (xer_overflow | xer_summary_overflow); 2712 1.1 christos CR0_COMPARE(t, 0, Rc); 2713 1.1 christos PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc); 2714 1.1 christos 2715 1.1 christos 0.31,6.RT,11.RA,16.RB,21./,22.73,31.Rc:XO:64::Multiply High Doubleword 2716 1.1 christos 2717 1.1 christos 0.31,6.RT,11.RA,16.RB,21./,22.75,31.Rc:XO::mulhw:Multiply High Word 2718 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0 2719 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0 2720 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 5, 5, 0 2721 1.1 christos *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0 2722 1.1 christos int64_t a = (int32_t)(*rA); 2723 1.1 christos int64_t b = (int32_t)(*rB); 2724 1.1 christos int64_t prod = a * b; 2725 1.1 christos signed_word t = EXTRACTED64(prod, 0, 31); 2726 1.1 christos *rT = t; 2727 1.1 christos CR0_COMPARE(t, 0, Rc); 2728 1.1 christos PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc); 2729 1.1 christos 2730 1.1 christos 0.31,6.RT,11.RA,16.RB,21./,22.9,31.Rc:XO:64::Multiply High Doubleword Unsigned 2731 1.1 christos 2732 1.1 christos 0.31,6.RT,11.RA,16.RB,21./,22.11,31.Rc:XO::mulhwu:Multiply High Word Unsigned 2733 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 10, 10, 0 2734 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0 2735 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 6, 6, 0 2736 1.1 christos *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 4, 4, 0 2737 1.1 christos uint64_t a = (uint32_t)(*rA); 2738 1.1 christos uint64_t b = (uint32_t)(*rB); 2739 1.1 christos uint64_t prod = a * b; 2740 1.1 christos signed_word t = EXTRACTED64(prod, 0, 31); 2741 1.1 christos *rT = t; 2742 1.1 christos CR0_COMPARE(t, 0, Rc); 2743 1.1 christos PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc); 2744 1.1 christos 2745 1.1 christos 0.31,6.RT,11.RA,16.RB,21.OE,22.489,31.Rc:XO:64::Divide Doubleword 2746 1.1 christos 2747 1.1 christos 0.31,6.RT,11.RA,16.RB,21.OE,22.491,31.Rc:XO::divw:Divide Word 2748 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0 2749 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0 2750 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0 2751 1.1 christos *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0 2752 1.1 christos int64_t dividend = (int32_t)(*rA); 2753 1.1 christos int64_t divisor = (int32_t)(*rB); 2754 1.1 christos if (divisor == 0 /* nb 0x8000..0 is sign extended */ 2755 1.1 christos || (dividend == 0x80000000 && divisor == -1)) { 2756 1.1 christos if (OE) 2757 1.1 christos XER |= (xer_overflow | xer_summary_overflow); 2758 1.1 christos CR0_COMPARE(0, 0, Rc); 2759 1.1 christos } 2760 1.1 christos else { 2761 1.1 christos int64_t quotent = dividend / divisor; 2762 1.1 christos *rT = quotent; 2763 1.1 christos CR0_COMPARE((signed_word)quotent, 0, Rc); 2764 1.1 christos } 2765 1.1 christos PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc); 2766 1.1 christos 2767 1.1 christos 0.31,6.RT,11.RA,16.RB,21.OE,22.457,31.Rc:XO:64::Divide Doubleword Unsigned 2768 1.1 christos 2769 1.1 christos 0.31,6.RT,11.RA,16.RB,21.OE,22.459,31.Rc:XO::divwu:Divide Word Unsigned 2770 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 36, 36, 0 2771 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0 2772 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 37, 37, 0 2773 1.1 christos *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 20, 20, 0 2774 1.1 christos uint64_t dividend = (uint32_t)(*rA); 2775 1.1 christos uint64_t divisor = (uint32_t)(*rB); 2776 1.1 christos if (divisor == 0) { 2777 1.1 christos if (OE) 2778 1.1 christos XER |= (xer_overflow | xer_summary_overflow); 2779 1.1 christos CR0_COMPARE(0, 0, Rc); 2780 1.1 christos } 2781 1.1 christos else { 2782 1.1 christos uint64_t quotent = dividend / divisor; 2783 1.1 christos *rT = quotent; 2784 1.1 christos CR0_COMPARE((signed_word)quotent, 0, Rc); 2785 1.1 christos } 2786 1.1 christos PPC_INSN_INT(RT_BITMASK, RA_BITMASK | RB_BITMASK, Rc); 2787 1.1 christos 2788 1.1 christos 2789 1.1 christos # 2790 1.1 christos # I.3.3.10 Fixed-Point Compare Instructions 2791 1.1 christos # 2792 1.1 christos 2793 1.1 christos 0.11,6.BF,9./,10.L,11.RA,16.SI:D:::Compare Immediate 2794 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2795 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2796 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0 2797 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2798 1.1 christos if (!is_64bit_mode && L) 2799 1.1 christos program_interrupt(processor, cia, 2800 1.1 christos illegal_instruction_program_interrupt); 2801 1.1 christos else { 2802 1.1 christos signed_word a; 2803 1.1 christos signed_word b = EXTS(SI); 2804 1.1 christos if (L == 0) 2805 1.1 christos a = EXTENDED(*rA); 2806 1.1 christos else 2807 1.1 christos a = *rA; 2808 1.1 christos CR_COMPARE(BF, a, b); 2809 1.1 christos } 2810 1.1 christos PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK); 2811 1.1 christos 2812 1.1 christos 0.31,6.BF,9./,10.L,11.RA,16.RB,21.0,31./:X:::Compare 2813 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2814 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2815 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0 2816 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2817 1.1 christos if (!is_64bit_mode && L) 2818 1.1 christos program_interrupt(processor, cia, 2819 1.1 christos illegal_instruction_program_interrupt); 2820 1.1 christos else { 2821 1.1 christos signed_word a; 2822 1.1 christos signed_word b; 2823 1.1 christos if (L == 0) { 2824 1.1 christos a = EXTENDED(*rA); 2825 1.1 christos b = EXTENDED(*rB); 2826 1.1 christos } 2827 1.1 christos else { 2828 1.1 christos a = *rA; 2829 1.1 christos b = *rB; 2830 1.1 christos } 2831 1.1 christos CR_COMPARE(BF, a, b); 2832 1.1 christos } 2833 1.1 christos PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK); 2834 1.1 christos 2835 1.1 christos 0.10,6.BF,9./,10.L,11.RA,16.UI:D:::Compare Logical Immediate 2836 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2837 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2838 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0 2839 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2840 1.1 christos if (!is_64bit_mode && L) 2841 1.1 christos program_interrupt(processor, cia, 2842 1.1 christos illegal_instruction_program_interrupt); 2843 1.1 christos else { 2844 1.1 christos unsigned_word a; 2845 1.1 christos unsigned_word b = UI; 2846 1.1 christos if (L == 0) 2847 1.1 christos a = MASKED(*rA, 32, 63); 2848 1.1 christos else 2849 1.1 christos a = *rA; 2850 1.1 christos CR_COMPARE(BF, a, b); 2851 1.1 christos } 2852 1.1 christos PPC_INSN_INT_CR(0, RA_BITMASK, BF_BITMASK); 2853 1.1 christos 2854 1.1 christos 0.31,6.BF,9./,10.L,11.RA,16.RB,21.32,31./:X:::Compare Logical 2855 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2856 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2857 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_SRU, 1, 1, 0 2858 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2859 1.1 christos if (!is_64bit_mode && L) 2860 1.1 christos program_interrupt(processor, cia, 2861 1.1 christos illegal_instruction_program_interrupt); 2862 1.1 christos else { 2863 1.1 christos unsigned_word a; 2864 1.1 christos unsigned_word b; 2865 1.1 christos if (L == 0) { 2866 1.1 christos a = MASKED(*rA, 32, 63); 2867 1.1 christos b = MASKED(*rB, 32, 63); 2868 1.1 christos } 2869 1.1 christos else { 2870 1.1 christos a = *rA; 2871 1.1 christos b = *rB; 2872 1.1 christos } 2873 1.1 christos CR_COMPARE(BF, a, b); 2874 1.1 christos } 2875 1.1 christos PPC_INSN_INT_CR(0, RA_BITMASK | RB_BITMASK, BF_BITMASK); 2876 1.1 christos 2877 1.1 christos 2878 1.1 christos # 2879 1.1 christos # I.3.3.11 Fixed-Point Trap Instructions 2880 1.1 christos # 2881 1.1 christos 2882 1.1 christos 0.2,6.TO,11.RA,16.SI:D:64::Trap Doubleword Immediate 2883 1.1 christos if (!is_64bit_mode) 2884 1.1 christos program_interrupt(processor, cia, 2885 1.1 christos illegal_instruction_program_interrupt); 2886 1.1 christos else { 2887 1.1 christos signed_word a = *rA; 2888 1.1 christos signed_word b = EXTS(SI); 2889 1.1 christos if ((a < b && TO{0}) 2890 1.1 christos || (a > b && TO{1}) 2891 1.1 christos || (a == b && TO{2}) 2892 1.1 christos || ((unsigned_word)a < (unsigned_word)b && TO{3}) 2893 1.1 christos || ((unsigned_word)a > (unsigned_word)b && TO{4}) 2894 1.1 christos ) 2895 1.1 christos program_interrupt(processor, cia, 2896 1.1 christos trap_program_interrupt); 2897 1.1 christos } 2898 1.1 christos 2899 1.1 christos 0.3,6.TO,11.RA,16.SI:D:::Trap Word Immediate 2900 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2901 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0 2902 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0 2903 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2904 1.1 christos signed_word a = EXTENDED(*rA); 2905 1.1 christos signed_word b = EXTS(SI); 2906 1.1 christos if ((a < b && TO{0}) 2907 1.1 christos || (a > b && TO{1}) 2908 1.1 christos || (a == b && TO{2}) 2909 1.1 christos || ((unsigned_word)a < (unsigned_word)b && TO{3}) 2910 1.1 christos || ((unsigned_word)a > (unsigned_word)b && TO{4}) 2911 1.1 christos ) 2912 1.1 christos program_interrupt(processor, cia, 2913 1.1 christos trap_program_interrupt); 2914 1.1 christos 2915 1.1 christos 0.31,6.TO,11.RA,16.RB,21.68,31./:X:64::Trap Doubleword 2916 1.1 christos if (!is_64bit_mode) 2917 1.1 christos program_interrupt(processor, cia, 2918 1.1 christos illegal_instruction_program_interrupt); 2919 1.1 christos else { 2920 1.1 christos signed_word a = *rA; 2921 1.1 christos signed_word b = *rB; 2922 1.1 christos if ((a < b && TO{0}) 2923 1.1 christos || (a > b && TO{1}) 2924 1.1 christos || (a == b && TO{2}) 2925 1.1 christos || ((unsigned_word)a < (unsigned_word)b && TO{3}) 2926 1.1 christos || ((unsigned_word)a > (unsigned_word)b && TO{4}) 2927 1.1 christos ) 2928 1.1 christos program_interrupt(processor, cia, 2929 1.1 christos trap_program_interrupt); 2930 1.1 christos } 2931 1.1 christos 2932 1.1 christos 0.31,6.TO,11.RA,16.RB,21.4,31./:X:::Trap Word 2933 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2934 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0 2935 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0 2936 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2937 1.1 christos signed_word a = EXTENDED(*rA); 2938 1.1 christos signed_word b = EXTENDED(*rB); 2939 1.1 christos if (TO == 12 && rA == rB) { 2940 1.1 christos ITRACE(trace_breakpoint, ("breakpoint\n")); 2941 1.1 christos cpu_halt(processor, cia, was_trap, 0); 2942 1.1 christos } 2943 1.1 christos else if ((a < b && TO{0}) 2944 1.1 christos || (a > b && TO{1}) 2945 1.1 christos || (a == b && TO{2}) 2946 1.1 christos || ((unsigned_word)a < (unsigned_word)b && TO{3}) 2947 1.1 christos || ((unsigned_word)a > (unsigned_word)b && TO{4}) 2948 1.1 christos ) 2949 1.1 christos program_interrupt(processor, cia, 2950 1.1 christos trap_program_interrupt); 2951 1.1 christos 2952 1.1 christos # 2953 1.1 christos # I.3.3.12 Fixed-Point Logical Instructions 2954 1.1 christos # 2955 1.1 christos 2956 1.1 christos 0.28,6.RS,11.RA,16.UI:D:::AND Immediate 2957 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2958 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2959 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2960 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2961 1.1 christos *rA = *rS & UI; 2962 1.1 christos CR0_COMPARE(*rA, 0, 1/*Rc*/); 2963 1.1 christos ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA)); 2964 1.1 christos PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/); 2965 1.1 christos 2966 1.1 christos 0.29,6.RS,11.RA,16.UI:D:::AND Immediate Shifted 2967 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2968 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2969 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2970 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2971 1.1 christos *rA = *rS & (UI << 16); 2972 1.1 christos CR0_COMPARE(*rA, 0, 1/*Rc*/); 2973 1.1 christos ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA)); 2974 1.1 christos PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 1/*Rc*/); 2975 1.1 christos 2976 1.1 christos 0.24,6.RS,11.RA,16.UI:D:::OR Immediate 2977 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2978 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2979 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2980 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2981 1.1 christos *rA = *rS | UI; 2982 1.1 christos ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA)); 2983 1.1 christos PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/); 2984 1.1 christos 2985 1.1 christos 0.25,6.RS,11.RA,16.UI:D:::OR Immediate Shifted 2986 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2987 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2988 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2989 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2990 1.1 christos *rA = *rS | (UI << 16); 2991 1.1 christos ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA)); 2992 1.1 christos PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/); 2993 1.1 christos 2994 1.1 christos 0.26,6.RS,11.RA,16.UI:D:::XOR Immediate 2995 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2996 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2997 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 2998 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 2999 1.1 christos *rA = *rS ^ UI; 3000 1.1 christos ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA)); 3001 1.1 christos PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/); 3002 1.1 christos 3003 1.1 christos 0.27,6.RS,11.RA,16.UI:D:::XOR Immediate Shifted 3004 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3005 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3006 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3007 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 3008 1.1 christos *rA = *rS ^ (UI << 16); 3009 1.1 christos ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA)); 3010 1.1 christos PPC_INSN_INT(RA_BITMASK, RS_BITMASK, 0/*Rc*/); 3011 1.1 christos 3012 1.1 christos 0.31,6.RS,11.RA,16.RB,21.28,31.Rc:X:::AND 3013 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3014 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3015 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3016 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 3017 1.1 christos *rA = *rS & *rB; 3018 1.1 christos CR0_COMPARE(*rA, 0, Rc); 3019 1.1 christos ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA)); 3020 1.1 christos PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc); 3021 1.1 christos 3022 1.1 christos 0.31,6.RS,11.RA,16.RB,21.444,31.Rc:X:::OR 3023 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3024 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3025 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3026 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 3027 1.1 christos *rA = *rS | *rB; 3028 1.1 christos CR0_COMPARE(*rA, 0, Rc); 3029 1.1 christos ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA)); 3030 1.1 christos PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc); 3031 1.1 christos 3032 1.1 christos 0.31,6.RS,11.RA,16.RB,21.316,31.Rc:X:::XOR 3033 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3034 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3035 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3036 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 3037 1.1 christos *rA = *rS ^ *rB; 3038 1.1 christos CR0_COMPARE(*rA, 0, Rc); 3039 1.1 christos ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA)); 3040 1.1 christos PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc); 3041 1.1 christos 3042 1.1 christos 0.31,6.RS,11.RA,16.RB,21.476,31.Rc:X:::NAND 3043 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3044 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3045 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3046 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 3047 1.1 christos *rA = ~(*rS & *rB); 3048 1.1 christos CR0_COMPARE(*rA, 0, Rc); 3049 1.1 christos ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA)); 3050 1.1 christos PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc); 3051 1.1 christos 3052 1.1 christos 0.31,6.RS,11.RA,16.RB,21.124,31.Rc:X:::NOR 3053 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3054 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3055 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3056 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 3057 1.1 christos *rA = ~(*rS | *rB); 3058 1.1 christos CR0_COMPARE(*rA, 0, Rc); 3059 1.1 christos ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA)); 3060 1.1 christos PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc); 3061 1.1 christos 3062 1.1 christos 0.31,6.RS,11.RA,16.RB,21.284,31.Rc:X:::Equivalent 3063 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3064 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3065 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3066 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 3067 1.1 christos *rA = ~(*rS ^ *rB); /* A === B */ 3068 1.1 christos CR0_COMPARE(*rA, 0, Rc); 3069 1.1 christos ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA)); 3070 1.1 christos PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc); 3071 1.1 christos 3072 1.1 christos 0.31,6.RS,11.RA,16.RB,21.60,31.Rc:X:::AND with Complement 3073 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3074 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3075 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3076 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 3077 1.1 christos *rA = *rS & ~*rB; 3078 1.1 christos CR0_COMPARE(*rA, 0, Rc); 3079 1.1 christos ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA)); 3080 1.1 christos PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc); 3081 1.1 christos 3082 1.1 christos 0.31,6.RS,11.RA,16.RB,21.412,31.Rc:X:::OR with Complement 3083 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3084 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3085 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3086 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 3087 1.1 christos *rA = *rS | ~*rB; 3088 1.1 christos CR0_COMPARE(*rA, 0, Rc); 3089 1.1 christos ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA)); 3090 1.1 christos PPC_INSN_INT(RA_BITMASK, RS_BITMASK | RB_BITMASK, Rc); 3091 1.1 christos 3092 1.1 christos 0.31,6.RS,11.RA,16./,21.954,31.Rc:X::extsb:Extend Sign Byte 3093 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3094 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3095 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3096 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 3097 1.1 christos *rA = (signed_word)(int8_t)*rS; 3098 1.1 christos CR0_COMPARE(*rA, 0, Rc); 3099 1.1 christos ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA)); 3100 1.1 christos PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc); 3101 1.1 christos 3102 1.1 christos 0.31,6.RS,11.RA,16./,21.922,31.Rc:X::extsh:Extend Sign Half Word 3103 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3104 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3105 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3106 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 3107 1.1 christos *rA = (signed_word)(int16_t)*rS; 3108 1.1 christos CR0_COMPARE(*rA, 0, Rc); 3109 1.1 christos ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA)); 3110 1.1 christos PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc); 3111 1.1 christos 3112 1.1 christos 0.31,6.RS,11.RA,16./,21.986,31.Rc:X:64::Extend Sign Word 3113 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3114 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3115 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3116 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 3117 1.1 christos # *rA = (signed_word)(int32_t)*rS; 3118 1.1 christos # CR0_COMPARE(*rA, 0, Rc); 3119 1.1 christos 3120 1.1 christos 0.31,6.RS,11.RA,16./,21.58,31.Rc:X:64::Count Leading Zeros Doubleword 3121 1.1 christos # int count = 0; 3122 1.1 christos # uint64_t mask = BIT64(0); 3123 1.1 christos # uint64_t source = *rS; 3124 1.1 christos # while (!(source & mask) && mask != 0) { 3125 1.1 christos # mask >>= 1; 3126 1.1 christos # count++; 3127 1.1 christos # } 3128 1.1 christos # *rA = count; 3129 1.1 christos # CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */ 3130 1.1 christos 3131 1.1 christos 0.31,6.RS,11.RA,16./,21.26,31.Rc:X:::Count Leading Zeros Word 3132 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3133 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3134 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3135 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 3136 1.1 christos int count = 0; 3137 1.1 christos uint32_t mask = BIT32(0); 3138 1.1 christos uint32_t source = *rS; 3139 1.1 christos while (!(source & mask) && mask != 0) { 3140 1.1 christos mask >>= 1; 3141 1.1 christos count++; 3142 1.1 christos } 3143 1.1 christos *rA = count; 3144 1.1 christos ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA)); 3145 1.1 christos CR0_COMPARE(count, 0, Rc); /* FIXME - is this correct */ 3146 1.1 christos 3147 1.1 christos 3148 1.1 christos # 3149 1.1 christos # I.3.3.13 Fixed-Point Rotate and Shift Instructions 3150 1.1 christos # 3151 1.1 christos 3152 1.1 christos 0.30,6.RS,11.RA,16.sh_0_4,21.mb,27.0,30.sh_5,31.Rc:MD:64::Rotate Left Doubleword Immediate then Clear Left 3153 1.1 christos # long n = (sh_5 << 4) | sh_0_4; 3154 1.1 christos # unsigned_word r = ROTL64(*rS, n); 3155 1.1 christos # long b = (mb_5 << 4) | mb_0_4; 3156 1.1 christos # unsigned_word m = MASK(b, 63); 3157 1.1 christos # signed_word result = r & m; 3158 1.1 christos # *rA = result; 3159 1.1 christos # ITRACE(trace_alu, (" Result = %ld (0x%lx)\n", (long)*rA, (long)*rA)); 3160 1.1 christos # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */ 3161 1.1 christos 3162 1.1 christos 0.30,6.RS,11.RA,16.sh_0_4,21.me,27.1,30.sh_5,31.Rc:MD:64::Rotate Left Doubleword Immediate then Clear Right 3163 1.1 christos # long n = (sh_5 << 4) | sh_0_4; 3164 1.1 christos # unsigned_word r = ROTL64(*rS, n); 3165 1.1 christos # long e = (me_5 << 4) | me_0_4; 3166 1.1 christos # unsigned_word m = MASK(0, e); 3167 1.1 christos # signed_word result = r & m; 3168 1.1 christos # *rA = result; 3169 1.1 christos # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */ 3170 1.1 christos 3171 1.1 christos 0.30,6.RS,11.RA,16.sh_0_4,21.mb,27.2,30.sh_5,31.Rc:MD:64::Rotate Left Doubleword Immediate then Clear 3172 1.1 christos # long n = (sh_5 << 4) | sh_0_4; 3173 1.1 christos # unsigned_word r = ROTL64(*rS, n); 3174 1.1 christos # long b = (mb_5 << 4) | mb_0_4; 3175 1.1 christos # unsigned_word m = MASK(0, (64-n)); 3176 1.1 christos # signed_word result = r & m; 3177 1.1 christos # *rA = result; 3178 1.1 christos # CR0_COMPARE(result, 0, Rc); /* FIXME - is this correct */ 3179 1.1 christos 3180 1.1 christos 0.21,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M:::Rotate Left Word Immediate then AND with Mask 3181 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3182 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3183 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3184 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 3185 1.1 christos long n = SH; 3186 1.1 christos uint32_t s = *rS; 3187 1.1 christos uint32_t r = ROTL32(s, n); 3188 1.1 christos uint32_t m = MASK(MB+32, ME+32); 3189 1.1 christos signed_word result = r & m; 3190 1.1 christos *rA = result; 3191 1.1 christos CR0_COMPARE(result, 0, Rc); 3192 1.1 christos ITRACE(trace_alu, 3193 1.1 christos ("n=%ld, s=0x%lx, r=0x%lx, m=0x%lx, result=0x%lx, cr=0x%lx\n", 3194 1.1 christos n, (unsigned long)s, (unsigned long)r, (unsigned long)m, 3195 1.1 christos (unsigned long)result, (unsigned long)CR)); 3196 1.1 christos PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc); 3197 1.1 christos 3198 1.1 christos 0.30,6.RS,11.RA,16.RB,21.mb,27.8,31.Rc:MDS:64::Rotate Left Doubleword then Clear Left 3199 1.1 christos # long n = MASKED(*rB, 58, 63); 3200 1.1 christos # unsigned_word r = ROTL64(*rS, n); 3201 1.1 christos # long b = (mb_5 << 4) | mb_0_4; 3202 1.1 christos # unsigned_word m = MASK(b, 63); 3203 1.1 christos # signed_word result = r & m; 3204 1.1 christos # *rA = result; 3205 1.1 christos # CR0_COMPARE(result, 0, Rc); 3206 1.1 christos 3207 1.1 christos 0.30,6.RS,11.RA,16.RB,21.me,27.9,31.Rc:MDS:64::Rotate Left Doubleword then Clear Right 3208 1.1 christos # long n = MASKED(*rB, 58, 63); 3209 1.1 christos # unsigned_word r = ROTL64(*rS, n); 3210 1.1 christos # long e = (me_5 << 4) | me_0_4; 3211 1.1 christos # unsigned_word m = MASK(0, e); 3212 1.1 christos # signed_word result = r & m; 3213 1.1 christos # *rA = result; 3214 1.1 christos # CR0_COMPARE(result, 0, Rc); 3215 1.1 christos 3216 1.1 christos 0.23,6.RS,11.RA,16.RB,21.MB,26.ME,31.Rc:M:::Rotate Left Word then AND with Mask 3217 1.1 christos long n = MASKED(*rB, 59, 63); 3218 1.1 christos uint32_t r = ROTL32(*rS, n); 3219 1.1 christos uint32_t m = MASK(MB+32, ME+32); 3220 1.1 christos signed_word result = r & m; 3221 1.1 christos *rA = result; 3222 1.1 christos CR0_COMPARE(result, 0, Rc); 3223 1.1 christos 3224 1.1 christos 0.30,6.RS,11.RA,16.sh_0_4,21.mb,27.3,30.sh_5,31.Rc:MD:64::Rotate Left Doubleword Immediate then Mask Insert 3225 1.1 christos # long n = (sh_5 << 4) | sh_0_4; 3226 1.1 christos # unsigned_word r = ROTL64(*rS, n); 3227 1.1 christos # long b = (mb_5 << 4) | mb_0_4; 3228 1.1 christos # unsigned_word m = MASK(b, (64-n)); 3229 1.1 christos # signed_word result = (r & m) | (*rA & ~m) 3230 1.1 christos # *rA = result; 3231 1.1 christos # CR0_COMPARE(result, 0, Rc); 3232 1.1 christos 3233 1.1 christos 0.20,6.RS,11.RA,16.SH,21.MB,26.ME,31.Rc:M::rlwimi:Rotate Left Word Immediate then Mask Insert 3234 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3235 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3236 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3237 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 3238 1.1 christos long n = SH; 3239 1.1 christos uint32_t r = ROTL32(*rS, n); 3240 1.1 christos uint32_t m = MASK(MB+32, ME+32); 3241 1.1 christos signed_word result = (r & m) | (*rA & ~m); 3242 1.1 christos *rA = result; 3243 1.1 christos ITRACE(trace_alu, (": n=%ld *rS=0x%lx r=0x%lx m=0x%lx result=0x%lx\n", 3244 1.1 christos n, (unsigned long)*rS, (unsigned long)r, (unsigned long)m, 3245 1.1 christos (unsigned long)result)); 3246 1.1 christos CR0_COMPARE(result, 0, Rc); 3247 1.1 christos PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc); 3248 1.1 christos 3249 1.1 christos 3250 1.1 christos 0.31,6.RS,11.RA,16.RB,21.27,31.Rc:X:64::Shift Left Doubleword 3251 1.1 christos 3252 1.1 christos 0.31,6.RS,11.RA,16.RB,21.24,31.Rc:X:::Shift Left Word 3253 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3254 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3255 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3256 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 3257 1.1 christos int n = MASKED(*rB, 58, 63); 3258 1.1 christos uint32_t source = *rS; 3259 1.1 christos signed_word shifted; 3260 1.1 christos if (n < 32) 3261 1.1 christos shifted = (source << n); 3262 1.1 christos else 3263 1.1 christos shifted = 0; 3264 1.1 christos *rA = shifted; 3265 1.1 christos CR0_COMPARE(shifted, 0, Rc); 3266 1.1 christos ITRACE(trace_alu, 3267 1.1 christos ("n=%d, source=0x%lx, shifted=0x%lx\n", 3268 1.1 christos n, (unsigned long)source, (unsigned long)shifted)); 3269 1.1 christos PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc); 3270 1.1 christos 3271 1.1 christos 0.31,6.RS,11.RA,16.RB,21.539,31.Rc:X:64::Shift Right Doubleword 3272 1.1 christos 3273 1.1 christos 0.31,6.RS,11.RA,16.RB,21.536,31.Rc:X:::Shift Right Word 3274 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3275 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3276 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3277 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 3278 1.1 christos int n = MASKED(*rB, 58, 63); 3279 1.1 christos uint32_t source = *rS; 3280 1.1 christos signed_word shifted; 3281 1.1 christos if (n < 32) 3282 1.1 christos shifted = (source >> n); 3283 1.1 christos else 3284 1.1 christos shifted = 0; 3285 1.1 christos *rA = shifted; 3286 1.1 christos CR0_COMPARE(shifted, 0, Rc); 3287 1.1 christos ITRACE(trace_alu, \ 3288 1.1 christos ("n=%d, source=0x%lx, shifted=0x%lx\n", 3289 1.1 christos n, (unsigned long)source, (unsigned long)shifted)); 3290 1.1 christos PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc); 3291 1.1 christos 3292 1.1 christos 0.31,6.RS,11.RA,16.sh_0_4,21.413,30.sh_5,31.Rc:XS:64::Shift Right Algebraic Doubleword Immediate 3293 1.1 christos 3294 1.1 christos 0.31,6.RS,11.RA,16.SH,21.824,31.Rc:X:::Shift Right Algebraic Word Immediate 3295 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3296 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3297 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3298 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 3299 1.1 christos int n = SH; 3300 1.1 christos signed_word r = ROTL32(*rS, /*64*/32-n); 3301 1.1 christos signed_word m = MASK(n+32, 63); 3302 1.1 christos int S = MASKED(*rS, 32, 32); 3303 1.1 christos signed_word shifted = (r & m) | (S ? ~m : 0); 3304 1.1 christos *rA = shifted; 3305 1.1 christos if (S && ((r & ~m) & MASK(32, 63)) != 0) 3306 1.1 christos XER |= xer_carry; 3307 1.1 christos else 3308 1.1 christos XER &= ~xer_carry; 3309 1.1 christos CR0_COMPARE(shifted, 0, Rc); 3310 1.1 christos ITRACE(trace_alu, (" Result = %ld (0x%lx), XER = %ld\n", 3311 1.1 christos (long)*rA, (long)*rA, (long)XER)); 3312 1.1 christos PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc); 3313 1.1 christos 3314 1.1 christos 0.31,6.RS,11.RA,16.RB,21.794,31.Rc:X:64::Shift Right Algebraic Doubleword 3315 1.1 christos 3316 1.1 christos 0.31,6.RS,11.RA,16.RB,21.792,31.Rc:X:::Shift Right Algebraic Word 3317 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3318 1.1 christos *603: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3319 1.1 christos *603e:PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3320 1.1 christos *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 3321 1.1 christos uint64_t mask; 3322 1.1 christos int n = MASKED(*rB, 59, 63); 3323 1.1 christos int32_t source = (int32_t)*rS; /* signed to keep sign bit */ 3324 1.1 christos int S = (MASKED(*rS,32,32) != 0); 3325 1.1 christos int64_t r = ((uint64_t) source); 3326 1.1 christos r = ((uint64_t) source) << 32 | (uint32_t) source; 3327 1.1 christos r = ROTL64(r,64-n); 3328 1.1 christos if (MASKED(*rB,58,58) == 0) 3329 1.1 christos mask = (uint64_t) MASK64(n+32,63); 3330 1.1 christos else 3331 1.1 christos mask = (uint64_t) 0; 3332 1.1 christos *rA = (signed_word) ((r & mask) | (((int64_t) -1*S) & ~mask)); /* if 64bit will sign extend */ 3333 1.1 christos if (S && (MASKED(r & ~mask,32,63)!=0)) 3334 1.1 christos XER |= xer_carry; 3335 1.1 christos else 3336 1.1 christos XER &= ~xer_carry; 3337 1.1 christos CR0_COMPARE(*rA, 0, Rc); 3338 1.1 christos ITRACE(trace_alu, (" Result = %ld (0x%lx), XER = %ld\n", 3339 1.1 christos (long)*rA, (long)*rA, (long)XER)); 3340 1.1 christos PPC_INSN_INT(RA_BITMASK, RS_BITMASK, Rc); 3341 1.1 christos 3342 1.1 christos # 3343 1.1 christos # I.3.3.14 Move to/from System Register Instructions 3344 1.1 christos # 3345 1.1 christos 3346 1.1 christos 0.31,6.RS,11.SPR,21.467,31./:XFX::mtspr %SPR, %RS:Move to Special Purpose Register 3347 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3348 1.1 christos *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0 3349 1.1 christos *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0 3350 1.1 christos *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0 3351 1.1 christos int n = (SPR{5:9} << 5) | SPR{0:4}; 3352 1.1 christos if (SPR{0} && IS_PROBLEM_STATE(processor)) 3353 1.1 christos program_interrupt(processor, cia, 3354 1.1 christos privileged_instruction_program_interrupt); 3355 1.1 christos else if (!spr_is_valid(n) 3356 1.1 christos || spr_is_readonly(n)) 3357 1.1 christos program_interrupt(processor, cia, 3358 1.1 christos illegal_instruction_program_interrupt); 3359 1.1 christos else { 3360 1.1 christos spreg new_val = (spr_length(n) == 64 3361 1.1 christos ? *rS 3362 1.1 christos : MASKED(*rS, 32, 63)); 3363 1.1 christos /* HACK - time base registers need to be updated immediately */ 3364 1.1 christos if (WITH_TIME_BASE) { 3365 1.1 christos switch (n) { 3366 1.1 christos case spr_tbu: 3367 1.1 christos cpu_set_time_base(processor, 3368 1.1 christos (MASKED64(cpu_get_time_base(processor), 32, 63) 3369 1.1 christos | INSERTED64(new_val, 0, 31))); 3370 1.1 christos break; 3371 1.1 christos case spr_tbl: 3372 1.1 christos cpu_set_time_base(processor, 3373 1.1 christos (MASKED64(cpu_get_time_base(processor), 0, 31) 3374 1.1 christos | INSERTED64(new_val, 32, 63))); 3375 1.1 christos break; 3376 1.1 christos case spr_dec: 3377 1.1 christos cpu_set_decrementer(processor, new_val); 3378 1.1 christos break; 3379 1.1 christos default: 3380 1.1 christos SPREG(n) = new_val; 3381 1.1 christos break; 3382 1.1 christos } 3383 1.1 christos } 3384 1.1 christos else { 3385 1.1 christos SPREG(n) = new_val; 3386 1.1 christos } 3387 1.1 christos } 3388 1.1 christos PPC_INSN_TO_SPR(RS_BITMASK, n); 3389 1.1 christos 3390 1.1 christos 0.31,6.RT,11.SPR,21.339,31./:XFX::mfspr %RT, %SPR:Move from Special Purpose Register 3391 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3392 1.1 christos *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 3393 1.1 christos *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 3394 1.1 christos *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0 3395 1.1 christos int n = (SPR{5:9} << 5) | SPR{0:4}; 3396 1.1 christos if (SPR{0} && IS_PROBLEM_STATE(processor)) 3397 1.1 christos program_interrupt(processor, cia, 3398 1.1 christos privileged_instruction_program_interrupt); 3399 1.1 christos else if (!spr_is_valid(n)) 3400 1.1 christos program_interrupt(processor, cia, 3401 1.1 christos illegal_instruction_program_interrupt); 3402 1.1 christos else { 3403 1.1 christos /* HACK - time base registers need to be calculated */ 3404 1.1 christos if (WITH_TIME_BASE) { 3405 1.1 christos switch (n) { 3406 1.1 christos case spr_dec: 3407 1.1 christos *rT = cpu_get_decrementer(processor); 3408 1.1 christos break; 3409 1.1 christos case spr_tbrl: 3410 1.1 christos if (is_64bit_implementation) *rT = TB; 3411 1.1 christos else *rT = EXTRACTED64(TB, 32, 63); 3412 1.1 christos break; 3413 1.1 christos case spr_tbru: 3414 1.1 christos if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31); 3415 1.1 christos else *rT = EXTRACTED64(TB, 0, 31); 3416 1.1 christos break; 3417 1.1 christos case spr_tbu: 3418 1.1 christos case spr_tbl: 3419 1.1 christos /* NOTE - these SPR's are not readable. Use mftb[ul] */ 3420 1.1 christos default: 3421 1.1 christos *rT = SPREG(n); 3422 1.1 christos break; 3423 1.1 christos } 3424 1.1 christos } 3425 1.1 christos else { 3426 1.1 christos *rT = SPREG(n); 3427 1.1 christos } 3428 1.1 christos } 3429 1.1 christos PPC_INSN_FROM_SPR(RT_BITMASK, n); 3430 1.1 christos 3431 1.1 christos 0.31,6.RS,11./,12.FXM,20./,21.144,31./:XFX::mtfcr:Move to Condition Register Fields 3432 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0 3433 1.1 christos *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 3434 1.1 christos *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 3435 1.1 christos *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0 3436 1.1 christos if (FXM == 0xff) { 3437 1.1 christos CR = *rS; 3438 1.1 christos } 3439 1.1 christos else { 3440 1.1 christos unsigned_word mask = 0; 3441 1.1 christos unsigned_word f; 3442 1.1 christos for (f = 0; f < 8; f++) { 3443 1.1 christos if (FXM & (0x80 >> f)) 3444 1.1 christos mask |= (0xf << 4*(7-f)); 3445 1.1 christos } 3446 1.1 christos CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask); 3447 1.1 christos } 3448 1.1 christos PPC_INSN_MTCR(RS_BITMASK, FXM); 3449 1.1 christos 3450 1.1 christos 0.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER 3451 1.1 christos # CR_SET(BF, EXTRACTED32(XER, 0, 3)); 3452 1.1 christos # MBLIT32(XER, 0, 3, 0); 3453 1.1 christos 3454 1.1 christos 0.31,6.RT,11./,16./,21.19,31./:X:::Move From Condition Register 3455 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3456 1.1 christos *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 3457 1.1 christos *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 3458 1.1 christos *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0 3459 1.1 christos *rT = (uint32_t)CR; 3460 1.1 christos PPC_INSN_MFCR(RT_BITMASK); 3461 1.1 christos 3462 1.1 christos # 3463 1.1 christos # I.4.6.2 Floating-Point Load Instructions 3464 1.1 christos # 3465 1.1 christos 3466 1.1 christos 0.48,6.FRT,11.RA,16.D:D:f:lfs:Load Floating-Point Single 3467 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0 3468 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3469 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3470 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 3471 1.1 christos unsigned_word b; 3472 1.1 christos unsigned_word EA; 3473 1.1 christos if (RA_is_0) b = 0; 3474 1.1 christos else b = *rA; 3475 1.1 christos EA = b + EXTS(D); 3476 1.1 christos *frT = DOUBLE(MEM(unsigned, EA, 4)); 3477 1.1 christos PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0); 3478 1.1 christos 3479 1.1 christos 0.31,6.FRT,11.RA,16.RB,21.535,31./:X:f::Load Floating-Point Single Indexed 3480 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0 3481 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3482 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3483 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 3484 1.1 christos unsigned_word b; 3485 1.1 christos unsigned_word EA; 3486 1.1 christos if (RA_is_0) b = 0; 3487 1.1 christos else b = *rA; 3488 1.1 christos EA = b + *rB; 3489 1.1 christos *frT = DOUBLE(MEM(unsigned, EA, 4)); 3490 1.1 christos PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0); 3491 1.1 christos 3492 1.1 christos 0.49,6.FRT,11.RA,16.D:D:f::Load Floating-Point Single with Update 3493 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0 3494 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3495 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3496 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 3497 1.1 christos unsigned_word EA; 3498 1.1 christos if (RA_is_0) 3499 1.1 christos program_interrupt(processor, cia, 3500 1.1 christos illegal_instruction_program_interrupt); 3501 1.1 christos EA = *rA + EXTS(D); 3502 1.1 christos *frT = DOUBLE(MEM(unsigned, EA, 4)); 3503 1.1 christos *rA = EA; 3504 1.1 christos PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0); 3505 1.1 christos 3506 1.1 christos 0.31,6.FRT,11.RA,16.RB,21.567,31./:X:f::Load Floating-Point Single with Update Indexed 3507 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0 3508 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3509 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3510 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 3511 1.1 christos unsigned_word EA; 3512 1.1 christos if (RA_is_0) 3513 1.1 christos program_interrupt(processor, cia, 3514 1.1 christos illegal_instruction_program_interrupt); 3515 1.1 christos EA = *rA + *rB; 3516 1.1 christos *frT = DOUBLE(MEM(unsigned, EA, 4)); 3517 1.1 christos *rA = EA; 3518 1.1 christos PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0); 3519 1.1 christos 3520 1.1 christos 0.50,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double 3521 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0 3522 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3523 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3524 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 3525 1.1 christos unsigned_word b; 3526 1.1 christos unsigned_word EA; 3527 1.1 christos if (RA_is_0) b = 0; 3528 1.1 christos else b = *rA; 3529 1.1 christos EA = b + EXTS(D); 3530 1.1 christos *frT = MEM(unsigned, EA, 8); 3531 1.1 christos PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1), 0); 3532 1.1 christos 3533 1.1 christos 0.31,6.FRT,11.RA,16.RB,21.599,31./:X:f::Load Floating-Point Double Indexed 3534 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0 3535 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3536 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3537 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 3538 1.1 christos unsigned_word b; 3539 1.1 christos unsigned_word EA; 3540 1.1 christos if (RA_is_0) b = 0; 3541 1.1 christos else b = *rA; 3542 1.1 christos EA = b + *rB; 3543 1.1 christos *frT = MEM(unsigned, EA, 8); 3544 1.1 christos PPC_INSN_INT_FLOAT(0, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0); 3545 1.1 christos 3546 1.1 christos 0.51,6.FRT,11.RA,16.D:D:f::Load Floating-Point Double with Update 3547 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0 3548 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3549 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3550 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 3551 1.1 christos unsigned_word EA; 3552 1.1 christos if (RA_is_0) 3553 1.1 christos program_interrupt(processor, cia, 3554 1.1 christos illegal_instruction_program_interrupt); 3555 1.1 christos EA = *rA + EXTS(D); 3556 1.1 christos *frT = MEM(unsigned, EA, 8); 3557 1.1 christos *rA = EA; 3558 1.1 christos PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1), 0); 3559 1.1 christos 3560 1.1 christos 0.31,6.FRT,11.RA,16.RB,21.631,31./:X:f::Load Floating-Point Double with Update Indexed 3561 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 3, 3, 0 3562 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3563 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3564 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 3565 1.1 christos unsigned_word EA; 3566 1.1 christos if (RA_is_0) 3567 1.1 christos program_interrupt(processor, cia, 3568 1.1 christos illegal_instruction_program_interrupt); 3569 1.1 christos EA = *rA + *rB; 3570 1.1 christos *frT = MEM(unsigned, EA, 8); 3571 1.1 christos *rA = EA; 3572 1.1 christos PPC_INSN_INT_FLOAT(RA_BITMASK, FRT_BITMASK, (RA_BITMASK & ~1) | RB_BITMASK, 0); 3573 1.1 christos 3574 1.1 christos 3575 1.1 christos # 3576 1.1 christos # I.4.6.3 Floating-Point Store Instructions 3577 1.1 christos # 3578 1.1 christos 3579 1.1 christos 0.52,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single 3580 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3581 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3582 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3583 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 3584 1.1 christos unsigned_word b; 3585 1.1 christos unsigned_word EA; 3586 1.1 christos if (RA_is_0) b = 0; 3587 1.1 christos else b = *rA; 3588 1.1 christos EA = b + EXTS(D); 3589 1.1 christos STORE(EA, 4, SINGLE(*frS)); 3590 1.1 christos PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK); 3591 1.1 christos 3592 1.1 christos 0.31,6.FRS,11.RA,16.RB,21.663,31./:X:f::Store Floating-Point Single Indexed 3593 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3594 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3595 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3596 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 3597 1.1 christos unsigned_word b; 3598 1.1 christos unsigned_word EA; 3599 1.1 christos if (RA_is_0) b = 0; 3600 1.1 christos else b = *rA; 3601 1.1 christos EA = b + *rB; 3602 1.1 christos STORE(EA, 4, SINGLE(*frS)); 3603 1.1 christos PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK); 3604 1.1 christos 3605 1.1 christos 0.53,6.FRS,11.RA,16.D:D:f::Store Floating-Point Single with Update 3606 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3607 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3608 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3609 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 3610 1.1 christos unsigned_word EA; 3611 1.1 christos if (RA_is_0) 3612 1.1 christos program_interrupt(processor, cia, 3613 1.1 christos illegal_instruction_program_interrupt); 3614 1.1 christos EA = *rA + EXTS(D); 3615 1.1 christos STORE(EA, 4, SINGLE(*frS)); 3616 1.1 christos *rA = EA; 3617 1.1 christos PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK); 3618 1.1 christos 3619 1.1 christos 0.31,6.FRS,11.RA,16.RB,21.695,31./:X:f::Store Floating-Point Single with Update Indexed 3620 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3621 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3622 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3623 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 3624 1.1 christos unsigned_word EA; 3625 1.1 christos if (RA_is_0) 3626 1.1 christos program_interrupt(processor, cia, 3627 1.1 christos illegal_instruction_program_interrupt); 3628 1.1 christos EA = *rA + *rB; 3629 1.1 christos STORE(EA, 4, SINGLE(*frS)); 3630 1.1 christos *rA = EA; 3631 1.1 christos PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK); 3632 1.1 christos 3633 1.1 christos 0.54,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double 3634 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3635 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3636 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3637 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 3638 1.1 christos unsigned_word b; 3639 1.1 christos unsigned_word EA; 3640 1.1 christos if (RA_is_0) b = 0; 3641 1.1 christos else b = *rA; 3642 1.1 christos EA = b + EXTS(D); 3643 1.1 christos STORE(EA, 8, *frS); 3644 1.1 christos PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1), FRS_BITMASK); 3645 1.1 christos 3646 1.1 christos 0.31,6.FRS,11.RA,16.RB,21.727,31./:X:f::Store Floating-Point Double Indexed 3647 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3648 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3649 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3650 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 3651 1.1 christos unsigned_word b; 3652 1.1 christos unsigned_word EA; 3653 1.1 christos if (RA_is_0) b = 0; 3654 1.1 christos else b = *rA; 3655 1.1 christos EA = b + *rB; 3656 1.1 christos STORE(EA, 8, *frS); 3657 1.1 christos PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK); 3658 1.1 christos 3659 1.1 christos 0.31,6.FRS,11.RA,16.RB,21.983,31./:X:f::Store Floating-Point Integer Word Indexed 3660 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3661 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3662 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 3663 1.1 christos unsigned_word b; 3664 1.1 christos unsigned_word EA; 3665 1.1 christos if (RA_is_0) b = 0; 3666 1.1 christos else b = *rA; 3667 1.1 christos EA = b + *rB; 3668 1.1 christos STORE(EA, 4, *frS); 3669 1.1 christos PPC_INSN_INT_FLOAT(0, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK); 3670 1.1 christos 3671 1.1 christos 0.55,6.FRS,11.RA,16.D:D:f::Store Floating-Point Double with Update 3672 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3673 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3674 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3675 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 3676 1.1 christos unsigned_word EA; 3677 1.1 christos if (RA_is_0) 3678 1.1 christos program_interrupt(processor, cia, 3679 1.1 christos illegal_instruction_program_interrupt); 3680 1.1 christos EA = *rA + EXTS(D); 3681 1.1 christos STORE(EA, 8, *frS); 3682 1.1 christos *rA = EA; 3683 1.1 christos PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1), FRS_BITMASK); 3684 1.1 christos 3685 1.1 christos 0.31,6.FRS,11.RA,16.RB,21.759,31./:X:f::Store Floating-Point Double with Update Indexed 3686 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 3687 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3688 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 2, 0 3689 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 3690 1.1 christos unsigned_word EA; 3691 1.1 christos if (RA_is_0) 3692 1.1 christos program_interrupt(processor, cia, 3693 1.1 christos illegal_instruction_program_interrupt); 3694 1.1 christos EA = *rA + *rB; 3695 1.1 christos STORE(EA, 8, *frS); 3696 1.1 christos *rA = EA; 3697 1.1 christos PPC_INSN_INT_FLOAT(RA_BITMASK, 0, (RA_BITMASK & ~1) | RB_BITMASK, FRS_BITMASK); 3698 1.1 christos 3699 1.1 christos 3700 1.1 christos # 3701 1.1 christos # I.4.6.4 Floating-Point Move Instructions 3702 1.1 christos # 3703 1.1 christos 3704 1.1 christos 0.63,6.FRT,11./,16.FRB,21.72,31.Rc:X:f::Floating Move Register 3705 1.1 christos *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0 3706 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3707 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3708 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3709 1.1 christos *frT = *frB; 3710 1.1 christos CR1_UPDATE(Rc); 3711 1.1 christos PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc); 3712 1.1 christos 3713 1.1 christos 0.63,6.FRT,11./,16.FRB,21.40,31.Rc:X:f::Floating Negate 3714 1.1 christos *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0 3715 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3716 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3717 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3718 1.1 christos *frT = *frB ^ BIT64(0); 3719 1.1 christos CR1_UPDATE(Rc); 3720 1.1 christos PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc); 3721 1.1 christos 3722 1.1 christos 0.63,6.FRT,11./,16.FRB,21.264,31.Rc:X:f::Floating Absolute Value 3723 1.1 christos *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0 3724 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3725 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3726 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3727 1.1 christos *frT = *frB & ~BIT64(0); 3728 1.1 christos CR1_UPDATE(Rc); 3729 1.1 christos PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc); 3730 1.1 christos 3731 1.1 christos 0.63,6.FRT,11./,16.FRB,21.136,31.Rc:X:f::Floating Negative Absolute Value 3732 1.1 christos *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0 3733 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3734 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3735 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3736 1.1 christos *frT = *frB | BIT64(0); 3737 1.1 christos CR1_UPDATE(Rc); 3738 1.1 christos PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc); 3739 1.1 christos 3740 1.1 christos 3741 1.1 christos # 3742 1.1 christos # I.4.6.5 Floating-Point Arithmetic Instructions 3743 1.1 christos # 3744 1.1 christos 3745 1.1 christos 0.63,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadd:Floating Add 3746 1.1 christos *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0 3747 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3748 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3749 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3750 1.1 christos FPSCR_BEGIN; 3751 1.1 christos if (is_invalid_operation(processor, cia, 3752 1.1 christos *frA, *frB, 3753 1.1 christos fpscr_vxsnan | fpscr_vxisi, 3754 1.1 christos 0, /*single?*/ 3755 1.1 christos 0) /*negate?*/) { 3756 1.1 christos invalid_arithemetic_operation(processor, cia, 3757 1.1 christos frT, *frA, *frB, 0, 3758 1.1 christos 0, /*instruction_is_frsp*/ 3759 1.1 christos 0, /*instruction_is_convert_to_64bit*/ 3760 1.1 christos 0, /*instruction_is_convert_to_32bit*/ 3761 1.1 christos 0); /*single-precision*/ 3762 1.1 christos } 3763 1.1 christos else { 3764 1.1 christos /*HACK!*/ 3765 1.1 christos double s = *(double*)frA + *(double*)frB; 3766 1.1 christos *(double*)frT = s; 3767 1.1 christos } 3768 1.1 christos FPSCR_END(Rc); 3769 1.1 christos PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc); 3770 1.1 christos 3771 1.1 christos 0.59,6.FRT,11.FRA,16.FRB,21./,26.21,31.Rc:A:f:fadds:Floating Add Single 3772 1.1 christos *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0 3773 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3774 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3775 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3776 1.1 christos FPSCR_BEGIN; 3777 1.1 christos if (is_invalid_operation(processor, cia, 3778 1.1 christos *frA, *frB, 3779 1.1 christos fpscr_vxsnan | fpscr_vxisi, 3780 1.1 christos 1, /*single?*/ 3781 1.1 christos 0) /*negate?*/) { 3782 1.1 christos invalid_arithemetic_operation(processor, cia, 3783 1.1 christos frT, *frA, *frB, 0, 3784 1.1 christos 0, /*instruction_is_frsp*/ 3785 1.1 christos 0, /*instruction_is_convert_to_64bit*/ 3786 1.1 christos 0, /*instruction_is_convert_to_32bit*/ 3787 1.1 christos 1); /*single-precision*/ 3788 1.1 christos } 3789 1.1 christos else { 3790 1.1 christos /*HACK!*/ 3791 1.1 christos float s = *(double*)frA + *(double*)frB; 3792 1.1 christos *(double*)frT = s; 3793 1.1 christos } 3794 1.1 christos FPSCR_END(Rc); 3795 1.1 christos PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc); 3796 1.1 christos 3797 1.1 christos 0.63,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsub:Floating Subtract 3798 1.1 christos *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0 3799 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3800 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3801 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3802 1.1 christos FPSCR_BEGIN; 3803 1.1 christos if (is_invalid_operation(processor, cia, 3804 1.1 christos *frA, *frB, 3805 1.1 christos fpscr_vxsnan | fpscr_vxisi, 3806 1.1 christos 0, /*single?*/ 3807 1.1 christos 1) /*negate?*/) { 3808 1.1 christos invalid_arithemetic_operation(processor, cia, 3809 1.1 christos frT, *frA, *frB, 0, 3810 1.1 christos 0, /*instruction_is_frsp*/ 3811 1.1 christos 0, /*instruction_is_convert_to_64bit*/ 3812 1.1 christos 0, /*instruction_is_convert_to_32bit*/ 3813 1.1 christos 0); /*single-precision*/ 3814 1.1 christos } 3815 1.1 christos else { 3816 1.1 christos /*HACK!*/ 3817 1.1 christos double s = *(double*)frA - *(double*)frB; 3818 1.1 christos *(double*)frT = s; 3819 1.1 christos } 3820 1.1 christos FPSCR_END(Rc); 3821 1.1 christos PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc); 3822 1.1 christos 3823 1.1 christos 0.59,6.FRT,11.FRA,16.FRB,21./,26.20,31.Rc:A:f:fsubs:Floating Subtract Single 3824 1.1 christos *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0 3825 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3826 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3827 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3828 1.1 christos FPSCR_BEGIN; 3829 1.1 christos if (is_invalid_operation(processor, cia, 3830 1.1 christos *frA, *frB, 3831 1.1 christos fpscr_vxsnan | fpscr_vxisi, 3832 1.1 christos 1, /*single?*/ 3833 1.1 christos 1) /*negate?*/) { 3834 1.1 christos invalid_arithemetic_operation(processor, cia, 3835 1.1 christos frT, *frA, *frB, 0, 3836 1.1 christos 0, /*instruction_is_frsp*/ 3837 1.1 christos 0, /*instruction_is_convert_to_64bit*/ 3838 1.1 christos 0, /*instruction_is_convert_to_32bit*/ 3839 1.1 christos 1); /*single-precision*/ 3840 1.1 christos } 3841 1.1 christos else { 3842 1.1 christos /*HACK!*/ 3843 1.1 christos float s = *(double*)frA - *(double*)frB; 3844 1.1 christos *(double*)frT = s; 3845 1.1 christos } 3846 1.1 christos FPSCR_END(Rc); 3847 1.1 christos PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc); 3848 1.1 christos 3849 1.1 christos 0.63,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmul:Floating Multiply 3850 1.1 christos *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0 3851 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0 3852 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0 3853 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3854 1.1 christos FPSCR_BEGIN; 3855 1.1 christos if (is_invalid_operation(processor, cia, 3856 1.1 christos *frA, *frC, 3857 1.1 christos fpscr_vxsnan | fpscr_vximz, 3858 1.1 christos 0, /*single?*/ 3859 1.1 christos 0) /*negate?*/) { 3860 1.1 christos invalid_arithemetic_operation(processor, cia, 3861 1.1 christos frT, *frA, 0, *frC, 3862 1.1 christos 0, /*instruction_is_frsp*/ 3863 1.1 christos 0, /*instruction_is_convert_to_64bit*/ 3864 1.1 christos 0, /*instruction_is_convert_to_32bit*/ 3865 1.1 christos 0); /*single-precision*/ 3866 1.1 christos } 3867 1.1 christos else { 3868 1.1 christos /*HACK!*/ 3869 1.1 christos double s = *(double*)frA * *(double*)frC; 3870 1.1 christos *(double*)frT = s; 3871 1.1 christos } 3872 1.1 christos FPSCR_END(Rc); 3873 1.1 christos PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc); 3874 1.1 christos 3875 1.1 christos 0.59,6.FRT,11.FRA,16./,21.FRC,26.25,31.Rc:A:f:fmuls:Floating Multiply Single 3876 1.1 christos *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0 3877 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3878 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3879 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3880 1.1 christos FPSCR_BEGIN; 3881 1.1 christos if (is_invalid_operation(processor, cia, 3882 1.1 christos *frA, *frC, 3883 1.1 christos fpscr_vxsnan | fpscr_vximz, 3884 1.1 christos 1, /*single?*/ 3885 1.1 christos 0) /*negate?*/) { 3886 1.1 christos invalid_arithemetic_operation(processor, cia, 3887 1.1 christos frT, *frA, 0, *frC, 3888 1.1 christos 0, /*instruction_is_frsp*/ 3889 1.1 christos 0, /*instruction_is_convert_to_64bit*/ 3890 1.1 christos 0, /*instruction_is_convert_to_32bit*/ 3891 1.1 christos 1); /*single-precision*/ 3892 1.1 christos } 3893 1.1 christos else { 3894 1.1 christos /*HACK!*/ 3895 1.1 christos float s = *(double*)frA * *(double*)frC; 3896 1.1 christos *(double*)frT = s; 3897 1.1 christos } 3898 1.1 christos FPSCR_END(Rc); 3899 1.1 christos PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRC_BITMASK, Rc); 3900 1.1 christos 3901 1.1 christos 0.63,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdiv:Floating Divide 3902 1.1 christos *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 31, 31, 0 3903 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0 3904 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 33, 33, 0 3905 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 32, 32, 0 3906 1.1 christos FPSCR_BEGIN; 3907 1.1 christos if (is_invalid_operation(processor, cia, 3908 1.1 christos *frA, *frB, 3909 1.1 christos fpscr_vxsnan | fpscr_vxzdz, 3910 1.1 christos 0, /*single?*/ 3911 1.1 christos 0) /*negate?*/) { 3912 1.1 christos invalid_arithemetic_operation(processor, cia, 3913 1.1 christos frT, *frA, *frB, 0, 3914 1.1 christos 0, /*instruction_is_frsp*/ 3915 1.1 christos 0, /*instruction_is_convert_to_64bit*/ 3916 1.1 christos 0, /*instruction_is_convert_to_32bit*/ 3917 1.1 christos 0); /*single-precision*/ 3918 1.1 christos } 3919 1.1 christos else if (is_invalid_zero_divide (processor, cia, 3920 1.1 christos *frA, *frB, 3921 1.1 christos 0 /*single?*/)) { 3922 1.1 christos invalid_zero_divide_operation (processor, cia, 3923 1.1 christos frT, *frA, *frB, 3924 1.1 christos 0 /*single?*/); 3925 1.1 christos } 3926 1.1 christos else { 3927 1.1 christos /*HACK!*/ 3928 1.1 christos double s = *(double*)frA / *(double*)frB; 3929 1.1 christos *(double*)frT = s; 3930 1.1 christos } 3931 1.1 christos FPSCR_END(Rc); 3932 1.1 christos PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc); 3933 1.1 christos 3934 1.1 christos 0.59,6.FRT,11.FRA,16.FRB,21./,26.18,31.Rc:A:f:fdivs:Floating Divide Single 3935 1.1 christos *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 17, 17, 0 3936 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0 3937 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0 3938 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 18, 18, 0 3939 1.1 christos FPSCR_BEGIN; 3940 1.1 christos if (is_invalid_operation(processor, cia, 3941 1.1 christos *frA, *frB, 3942 1.1 christos fpscr_vxsnan | fpscr_vxzdz, 3943 1.1 christos 1, /*single?*/ 3944 1.1 christos 0) /*negate?*/) { 3945 1.1 christos invalid_arithemetic_operation(processor, cia, 3946 1.1 christos frT, *frA, *frB, 0, 3947 1.1 christos 0, /*instruction_is_frsp*/ 3948 1.1 christos 0, /*instruction_is_convert_to_64bit*/ 3949 1.1 christos 0, /*instruction_is_convert_to_32bit*/ 3950 1.1 christos 1); /*single-precision*/ 3951 1.1 christos } 3952 1.1 christos else if (is_invalid_zero_divide (processor, cia, 3953 1.1 christos *frA, *frB, 3954 1.1 christos 1 /*single?*/)) { 3955 1.1 christos invalid_zero_divide_operation (processor, cia, 3956 1.1 christos frT, *frA, *frB, 3957 1.1 christos 1 /*single?*/); 3958 1.1 christos } 3959 1.1 christos else { 3960 1.1 christos /*HACK!*/ 3961 1.1 christos float s = *(double*)frA / *(double*)frB; 3962 1.1 christos *(double*)frT = s; 3963 1.1 christos } 3964 1.1 christos FPSCR_END(Rc); 3965 1.1 christos PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK, Rc); 3966 1.1 christos 3967 1.1.1.2 christos 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f:fmadd:Floating Multiply-Add 3968 1.1 christos *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0 3969 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0 3970 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0 3971 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 3972 1.1 christos FPSCR_BEGIN; 3973 1.1 christos double product; /*HACK! - incorrectly losing precision ... */ 3974 1.1 christos /* compute the multiply */ 3975 1.1 christos if (is_invalid_operation(processor, cia, 3976 1.1 christos *frA, *frC, 3977 1.1 christos fpscr_vxsnan | fpscr_vximz, 3978 1.1 christos 0, /*single?*/ 3979 1.1 christos 0) /*negate?*/) { 3980 1.1 christos union { double d; uint64_t u; } tmp; 3981 1.1 christos invalid_arithemetic_operation(processor, cia, 3982 1.1 christos &tmp.u, *frA, 0, *frC, 3983 1.1 christos 0, /*instruction_is_frsp*/ 3984 1.1 christos 0, /*instruction_is_convert_to_64bit*/ 3985 1.1 christos 0, /*instruction_is_convert_to_32bit*/ 3986 1.1 christos 0); /*single-precision*/ 3987 1.1 christos product = tmp.d; 3988 1.1 christos } 3989 1.1 christos else { 3990 1.1 christos /*HACK!*/ 3991 1.1 christos product = *(double*)frA * *(double*)frC; 3992 1.1 christos } 3993 1.1 christos /* compute the add */ 3994 1.1 christos if (is_invalid_operation(processor, cia, 3995 1.1 christos product, *frB, 3996 1.1 christos fpscr_vxsnan | fpscr_vxisi, 3997 1.1 christos 0, /*single?*/ 3998 1.1 christos 0) /*negate?*/) { 3999 1.1 christos invalid_arithemetic_operation(processor, cia, 4000 1.1 christos frT, product, *frB, 0, 4001 1.1 christos 0, /*instruction_is_frsp*/ 4002 1.1 christos 0, /*instruction_is_convert_to_64bit*/ 4003 1.1 christos 0, /*instruction_is_convert_to_32bit*/ 4004 1.1 christos 0); /*single-precision*/ 4005 1.1 christos } 4006 1.1 christos else { 4007 1.1 christos /*HACK!*/ 4008 1.1 christos double s = product + *(double*)frB; 4009 1.1 christos *(double*)frT = s; 4010 1.1 christos } 4011 1.1 christos FPSCR_END(Rc); 4012 1.1 christos PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc); 4013 1.1 christos 4014 1.1.1.2 christos 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.29,31.Rc:A:f::Floating Multiply-Add Single 4015 1.1 christos *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0 4016 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4017 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4018 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4019 1.1 christos FPSCR_BEGIN; 4020 1.1 christos float product; /*HACK! - incorrectly losing precision ... */ 4021 1.1 christos /* compute the multiply */ 4022 1.1 christos if (is_invalid_operation(processor, cia, 4023 1.1 christos *frA, *frC, 4024 1.1 christos fpscr_vxsnan | fpscr_vximz, 4025 1.1 christos 1, /*single?*/ 4026 1.1 christos 0) /*negate?*/) { 4027 1.1 christos union { double d; uint64_t u; } tmp; 4028 1.1 christos invalid_arithemetic_operation(processor, cia, 4029 1.1 christos &tmp.u, *frA, 0, *frC, 4030 1.1 christos 0, /*instruction_is_frsp*/ 4031 1.1 christos 0, /*instruction_is_convert_to_64bit*/ 4032 1.1 christos 0, /*instruction_is_convert_to_32bit*/ 4033 1.1 christos 0); /*single-precision*/ 4034 1.1 christos product = tmp.d; 4035 1.1 christos } 4036 1.1 christos else { 4037 1.1 christos /*HACK!*/ 4038 1.1 christos product = *(double*)frA * *(double*)frC; 4039 1.1 christos } 4040 1.1 christos /* compute the add */ 4041 1.1 christos if (is_invalid_operation(processor, cia, 4042 1.1 christos product, *frB, 4043 1.1 christos fpscr_vxsnan | fpscr_vxisi, 4044 1.1 christos 1, /*single?*/ 4045 1.1 christos 0) /*negate?*/) { 4046 1.1 christos invalid_arithemetic_operation(processor, cia, 4047 1.1 christos frT, product, *frB, 0, 4048 1.1 christos 0, /*instruction_is_frsp*/ 4049 1.1 christos 0, /*instruction_is_convert_to_64bit*/ 4050 1.1 christos 0, /*instruction_is_convert_to_32bit*/ 4051 1.1 christos 0); /*single-precision*/ 4052 1.1 christos } 4053 1.1 christos else { 4054 1.1 christos /*HACK!*/ 4055 1.1 christos float s = product + *(double*)frB; 4056 1.1 christos *(double*)frT = (double)s; 4057 1.1 christos } 4058 1.1 christos FPSCR_END(Rc); 4059 1.1 christos PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc); 4060 1.1 christos 4061 1.1.1.2 christos 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract 4062 1.1 christos *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0 4063 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0 4064 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0 4065 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4066 1.1 christos FPSCR_BEGIN; 4067 1.1 christos double product; /*HACK! - incorrectly losing precision ... */ 4068 1.1 christos /* compute the multiply */ 4069 1.1 christos if (is_invalid_operation(processor, cia, 4070 1.1 christos *frA, *frC, 4071 1.1 christos fpscr_vxsnan | fpscr_vximz, 4072 1.1 christos 0, /*single?*/ 4073 1.1 christos 0) /*negate?*/) { 4074 1.1 christos union { double d; uint64_t u; } tmp; 4075 1.1 christos invalid_arithemetic_operation(processor, cia, 4076 1.1 christos &tmp.u, *frA, 0, *frC, 4077 1.1 christos 0, /*instruction_is_frsp*/ 4078 1.1 christos 0, /*instruction_is_convert_to_64bit*/ 4079 1.1 christos 0, /*instruction_is_convert_to_32bit*/ 4080 1.1 christos 0); /*single-precision*/ 4081 1.1 christos product = tmp.d; 4082 1.1 christos } 4083 1.1 christos else { 4084 1.1 christos /*HACK!*/ 4085 1.1 christos product = *(double*)frA * *(double*)frC; 4086 1.1 christos } 4087 1.1 christos /* compute the subtract */ 4088 1.1 christos if (is_invalid_operation(processor, cia, 4089 1.1 christos product, *frB, 4090 1.1 christos fpscr_vxsnan | fpscr_vxisi, 4091 1.1 christos 0, /*single?*/ 4092 1.1 christos 0) /*negate?*/) { 4093 1.1 christos invalid_arithemetic_operation(processor, cia, 4094 1.1 christos frT, product, *frB, 0, 4095 1.1 christos 0, /*instruction_is_frsp*/ 4096 1.1 christos 0, /*instruction_is_convert_to_64bit*/ 4097 1.1 christos 0, /*instruction_is_convert_to_32bit*/ 4098 1.1 christos 0); /*single-precision*/ 4099 1.1 christos } 4100 1.1 christos else { 4101 1.1 christos /*HACK!*/ 4102 1.1 christos double s = product - *(double*)frB; 4103 1.1 christos *(double*)frT = s; 4104 1.1 christos } 4105 1.1 christos FPSCR_END(Rc); 4106 1.1 christos PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc); 4107 1.1 christos 4108 1.1.1.2 christos 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.28,31.Rc:A:f::Floating Multiply-Subtract Single 4109 1.1 christos *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0 4110 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4111 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4112 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4113 1.1 christos FPSCR_BEGIN; 4114 1.1 christos float product; /*HACK! - incorrectly losing precision ... */ 4115 1.1 christos /* compute the multiply */ 4116 1.1 christos if (is_invalid_operation(processor, cia, 4117 1.1 christos *frA, *frC, 4118 1.1 christos fpscr_vxsnan | fpscr_vximz, 4119 1.1 christos 1, /*single?*/ 4120 1.1 christos 0) /*negate?*/) { 4121 1.1 christos union { double d; uint64_t u; } tmp; 4122 1.1 christos invalid_arithemetic_operation(processor, cia, 4123 1.1 christos &tmp.u, *frA, 0, *frC, 4124 1.1 christos 0, /*instruction_is_frsp*/ 4125 1.1 christos 0, /*instruction_is_convert_to_64bit*/ 4126 1.1 christos 0, /*instruction_is_convert_to_32bit*/ 4127 1.1 christos 0); /*single-precision*/ 4128 1.1 christos product = tmp.d; 4129 1.1 christos } 4130 1.1 christos else { 4131 1.1 christos /*HACK!*/ 4132 1.1 christos product = *(double*)frA * *(double*)frC; 4133 1.1 christos } 4134 1.1 christos /* compute the subtract */ 4135 1.1 christos if (is_invalid_operation(processor, cia, 4136 1.1 christos product, *frB, 4137 1.1 christos fpscr_vxsnan | fpscr_vxisi, 4138 1.1 christos 1, /*single?*/ 4139 1.1 christos 0) /*negate?*/) { 4140 1.1 christos invalid_arithemetic_operation(processor, cia, 4141 1.1 christos frT, product, *frB, 0, 4142 1.1 christos 0, /*instruction_is_frsp*/ 4143 1.1 christos 0, /*instruction_is_convert_to_64bit*/ 4144 1.1 christos 0, /*instruction_is_convert_to_32bit*/ 4145 1.1 christos 0); /*single-precision*/ 4146 1.1 christos } 4147 1.1 christos else { 4148 1.1 christos /*HACK!*/ 4149 1.1 christos float s = product - *(double*)frB; 4150 1.1 christos *(double*)frT = (double)s; 4151 1.1 christos } 4152 1.1 christos FPSCR_END(Rc); 4153 1.1 christos PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc); 4154 1.1 christos 4155 1.1.1.2 christos 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add 4156 1.1 christos *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0 4157 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0 4158 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0 4159 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4160 1.1 christos FPSCR_BEGIN; 4161 1.1 christos double product; /*HACK! - incorrectly losing precision ... */ 4162 1.1 christos /* compute the multiply */ 4163 1.1 christos if (is_invalid_operation(processor, cia, 4164 1.1 christos *frA, *frC, 4165 1.1 christos fpscr_vxsnan | fpscr_vximz, 4166 1.1 christos 0, /*single?*/ 4167 1.1 christos 0) /*negate?*/) { 4168 1.1 christos union { double d; uint64_t u; } tmp; 4169 1.1 christos invalid_arithemetic_operation(processor, cia, 4170 1.1 christos &tmp.u, *frA, 0, *frC, 4171 1.1 christos 0, /*instruction_is_frsp*/ 4172 1.1 christos 0, /*instruction_is_convert_to_64bit*/ 4173 1.1 christos 0, /*instruction_is_convert_to_32bit*/ 4174 1.1 christos 0); /*single-precision*/ 4175 1.1 christos product = tmp.d; 4176 1.1 christos } 4177 1.1 christos else { 4178 1.1 christos /*HACK!*/ 4179 1.1 christos product = *(double*)frA * *(double*)frC; 4180 1.1 christos } 4181 1.1 christos /* compute the add */ 4182 1.1 christos if (is_invalid_operation(processor, cia, 4183 1.1 christos product, *frB, 4184 1.1 christos fpscr_vxsnan | fpscr_vxisi, 4185 1.1 christos 0, /*single?*/ 4186 1.1 christos 0) /*negate?*/) { 4187 1.1 christos invalid_arithemetic_operation(processor, cia, 4188 1.1 christos frT, product, *frB, 0, 4189 1.1 christos 0, /*instruction_is_frsp*/ 4190 1.1 christos 0, /*instruction_is_convert_to_64bit*/ 4191 1.1 christos 0, /*instruction_is_convert_to_32bit*/ 4192 1.1 christos 0); /*single-precision*/ 4193 1.1 christos } 4194 1.1 christos else { 4195 1.1 christos /*HACK!*/ 4196 1.1 christos double s = -(product + *(double*)frB); 4197 1.1 christos *(double*)frT = s; 4198 1.1 christos } 4199 1.1 christos FPSCR_END(Rc); 4200 1.1 christos PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc); 4201 1.1 christos 4202 1.1.1.2 christos 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.31,31.Rc:A:f::Floating Negative Multiply-Add Single 4203 1.1 christos *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0 4204 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4205 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4206 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4207 1.1 christos FPSCR_BEGIN; 4208 1.1 christos float product; /*HACK! - incorrectly losing precision ... */ 4209 1.1 christos /* compute the multiply */ 4210 1.1 christos if (is_invalid_operation(processor, cia, 4211 1.1 christos *frA, *frC, 4212 1.1 christos fpscr_vxsnan | fpscr_vximz, 4213 1.1 christos 1, /*single?*/ 4214 1.1 christos 0) /*negate?*/) { 4215 1.1 christos union { double d; uint64_t u; } tmp; 4216 1.1 christos invalid_arithemetic_operation(processor, cia, 4217 1.1 christos &tmp.u, *frA, 0, *frC, 4218 1.1 christos 0, /*instruction_is_frsp*/ 4219 1.1 christos 0, /*instruction_is_convert_to_64bit*/ 4220 1.1 christos 0, /*instruction_is_convert_to_32bit*/ 4221 1.1 christos 0); /*single-precision*/ 4222 1.1 christos product = tmp.d; 4223 1.1 christos } 4224 1.1 christos else { 4225 1.1 christos /*HACK!*/ 4226 1.1 christos product = *(double*)frA * *(double*)frC; 4227 1.1 christos } 4228 1.1 christos /* compute the add */ 4229 1.1 christos if (is_invalid_operation(processor, cia, 4230 1.1 christos product, *frB, 4231 1.1 christos fpscr_vxsnan | fpscr_vxisi, 4232 1.1 christos 1, /*single?*/ 4233 1.1 christos 0) /*negate?*/) { 4234 1.1 christos invalid_arithemetic_operation(processor, cia, 4235 1.1 christos frT, product, *frB, 0, 4236 1.1 christos 0, /*instruction_is_frsp*/ 4237 1.1 christos 0, /*instruction_is_convert_to_64bit*/ 4238 1.1 christos 0, /*instruction_is_convert_to_32bit*/ 4239 1.1 christos 0); /*single-precision*/ 4240 1.1 christos } 4241 1.1 christos else { 4242 1.1 christos /*HACK!*/ 4243 1.1 christos float s = -(product + *(double*)frB); 4244 1.1 christos *(double*)frT = (double)s; 4245 1.1 christos } 4246 1.1 christos FPSCR_END(Rc); 4247 1.1 christos PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc); 4248 1.1 christos 4249 1.1.1.2 christos 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract 4250 1.1 christos *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 5, 5, 0 4251 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0 4252 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 2, 4, 0 4253 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4254 1.1 christos FPSCR_BEGIN; 4255 1.1 christos double product; /*HACK! - incorrectly losing precision ... */ 4256 1.1 christos /* compute the multiply */ 4257 1.1 christos if (is_invalid_operation(processor, cia, 4258 1.1 christos *frA, *frC, 4259 1.1 christos fpscr_vxsnan | fpscr_vximz, 4260 1.1 christos 0, /*single?*/ 4261 1.1 christos 0) /*negate?*/) { 4262 1.1 christos union { double d; uint64_t u; } tmp; 4263 1.1 christos invalid_arithemetic_operation(processor, cia, 4264 1.1 christos &tmp.u, *frA, 0, *frC, 4265 1.1 christos 0, /*instruction_is_frsp*/ 4266 1.1 christos 0, /*instruction_is_convert_to_64bit*/ 4267 1.1 christos 0, /*instruction_is_convert_to_32bit*/ 4268 1.1 christos 0); /*single-precision*/ 4269 1.1 christos product = tmp.d; 4270 1.1 christos } 4271 1.1 christos else { 4272 1.1 christos /*HACK!*/ 4273 1.1 christos product = *(double*)frA * *(double*)frC; 4274 1.1 christos } 4275 1.1 christos /* compute the subtract */ 4276 1.1 christos if (is_invalid_operation(processor, cia, 4277 1.1 christos product, *frB, 4278 1.1 christos fpscr_vxsnan | fpscr_vxisi, 4279 1.1 christos 0, /*single?*/ 4280 1.1 christos 0) /*negate?*/) { 4281 1.1 christos invalid_arithemetic_operation(processor, cia, 4282 1.1 christos frT, product, *frB, 0, 4283 1.1 christos 0, /*instruction_is_frsp*/ 4284 1.1 christos 0, /*instruction_is_convert_to_64bit*/ 4285 1.1 christos 0, /*instruction_is_convert_to_32bit*/ 4286 1.1 christos 0); /*single-precision*/ 4287 1.1 christos } 4288 1.1 christos else { 4289 1.1 christos /*HACK!*/ 4290 1.1 christos double s = -(product - *(double*)frB); 4291 1.1 christos *(double*)frT = s; 4292 1.1 christos } 4293 1.1 christos FPSCR_END(Rc); 4294 1.1 christos PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc); 4295 1.1 christos 4296 1.1.1.2 christos 0.59,6.FRT,11.FRA,16.FRB,21.FRC,26.30,31.Rc:A:f::Floating Negative Multiply-Subtract Single 4297 1.1 christos *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0 4298 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4299 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4300 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4301 1.1 christos FPSCR_BEGIN; 4302 1.1 christos float product; /*HACK! - incorrectly losing precision ... */ 4303 1.1 christos /* compute the multiply */ 4304 1.1 christos if (is_invalid_operation(processor, cia, 4305 1.1 christos *frA, *frC, 4306 1.1 christos fpscr_vxsnan | fpscr_vximz, 4307 1.1 christos 1, /*single?*/ 4308 1.1 christos 0) /*negate?*/) { 4309 1.1 christos union { double d; uint64_t u; } tmp; 4310 1.1 christos invalid_arithemetic_operation(processor, cia, 4311 1.1 christos &tmp.u, *frA, 0, *frC, 4312 1.1 christos 0, /*instruction_is_frsp*/ 4313 1.1 christos 0, /*instruction_is_convert_to_64bit*/ 4314 1.1 christos 0, /*instruction_is_convert_to_32bit*/ 4315 1.1 christos 0); /*single-precision*/ 4316 1.1 christos product = tmp.d; 4317 1.1 christos } 4318 1.1 christos else { 4319 1.1 christos /*HACK!*/ 4320 1.1 christos product = *(double*)frA * *(double*)frC; 4321 1.1 christos } 4322 1.1 christos /* compute the subtract */ 4323 1.1 christos if (is_invalid_operation(processor, cia, 4324 1.1 christos product, *frB, 4325 1.1 christos fpscr_vxsnan | fpscr_vxisi, 4326 1.1 christos 1, /*single?*/ 4327 1.1 christos 0) /*negate?*/) { 4328 1.1 christos invalid_arithemetic_operation(processor, cia, 4329 1.1 christos frT, product, *frB, 0, 4330 1.1 christos 0, /*instruction_is_frsp*/ 4331 1.1 christos 0, /*instruction_is_convert_to_64bit*/ 4332 1.1 christos 0, /*instruction_is_convert_to_32bit*/ 4333 1.1 christos 0); /*single-precision*/ 4334 1.1 christos } 4335 1.1 christos else { 4336 1.1 christos /*HACK!*/ 4337 1.1 christos float s = -(product - *(double*)frB); 4338 1.1 christos *(double*)frT = (double)s; 4339 1.1 christos } 4340 1.1 christos FPSCR_END(Rc); 4341 1.1 christos PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc); 4342 1.1 christos 4343 1.1 christos 4344 1.1 christos # 4345 1.1 christos # I.4.6.6 Floating-Point Rounding and Conversion Instructions 4346 1.1 christos # 4347 1.1 christos 4348 1.1 christos 0.63,6.FRT,11./,16.FRB,21.12,31.Rc:X:f::Floating Round to Single-Precision 4349 1.1 christos *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0 4350 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4351 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4352 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4353 1.1 christos int sign; 4354 1.1 christos int exp; 4355 1.1 christos uint64_t frac_grx; 4356 1.1 christos /***/ 4357 1.1 christos /* split off cases for what to do */ 4358 1.1 christos if (EXTRACTED64(*frB, 1, 11) < 897 4359 1.1 christos && EXTRACTED64(*frB, 1, 63) > 0) { 4360 1.1 christos if ((FPSCR & fpscr_ue) == 0) GOTO(Disabled_Exponent_Underflow); 4361 1.1 christos if ((FPSCR & fpscr_ue) != 0) GOTO(Enabled_Exponent_Underflow); 4362 1.1 christos } 4363 1.1 christos if (EXTRACTED64(*frB, 1, 11) > 1150 4364 1.1 christos && EXTRACTED64(*frB, 1, 11) < 2047) { 4365 1.1 christos if ((FPSCR & fpscr_oe) == 0) GOTO(Disabled_Exponent_Overflow); 4366 1.1 christos if ((FPSCR & fpscr_oe) != 0) GOTO(Enabled_Exponent_Overflow); 4367 1.1 christos } 4368 1.1 christos if (EXTRACTED64(*frB, 1, 11) > 896 4369 1.1 christos && EXTRACTED64(*frB, 1, 11) < 1151) GOTO(Normal_Operand); 4370 1.1 christos if (EXTRACTED64(*frB, 1, 63) == 0) GOTO(Zero_Operand); 4371 1.1 christos if (EXTRACTED64(*frB, 1, 11) == 2047) { 4372 1.1 christos if (EXTRACTED64(*frB, 12, 63) == 0) GOTO(Infinity_Operand); 4373 1.1 christos if (EXTRACTED64(*frB, 12, 12) == 1) GOTO(QNaN_Operand); 4374 1.1 christos if (EXTRACTED64(*frB, 12, 12) == 0 4375 1.1 christos && EXTRACTED64(*frB, 13, 63) > 0) GOTO(SNaN_Operand); 4376 1.1 christos } 4377 1.1 christos /**/ 4378 1.1 christos LABEL(Disabled_Exponent_Underflow): 4379 1.1 christos sign = EXTRACTED64(*frB, 0, 0); 4380 1.1 christos if (EXTRACTED64(*frB, 1, 11) == 0) { 4381 1.1 christos exp = -1022; 4382 1.1 christos frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52); 4383 1.1 christos } 4384 1.1 christos if (EXTRACTED64(*frB, 1, 11) > 0) { 4385 1.1 christos exp = EXTRACTED64(*frB, 1, 11) - 1023; 4386 1.1 christos frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52); 4387 1.1 christos } 4388 1.1 christos /* G|R|X == zero from above */ 4389 1.1 christos while (exp < -126) { 4390 1.1 christos exp = exp + 1; 4391 1.1 christos frac_grx = (INSERTED64(EXTRACTED64(frac_grx, 0, 54), 1, 55) 4392 1.1 christos | MASKED64(frac_grx, 55, 55)); 4393 1.1 christos } 4394 1.1 christos FPSCR_SET_UX(EXTRACTED64(frac_grx, 24, 55) > 0); 4395 1.1 christos Round_Single(processor, sign, &exp, &frac_grx); 4396 1.1 christos FPSCR_SET_XX(FPSCR & fpscr_fi); 4397 1.1 christos if (EXTRACTED64(frac_grx, 0, 52) == 0) { 4398 1.1 christos *frT = INSERTED64(sign, 0, 0); 4399 1.1 christos if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero); 4400 1.1 christos if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero); 4401 1.1 christos } 4402 1.1 christos if (EXTRACTED64(frac_grx, 0, 52) > 0) { 4403 1.1 christos if (EXTRACTED64(frac_grx, 0, 0) == 1) { 4404 1.1 christos if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number); 4405 1.1 christos if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number); 4406 1.1 christos } 4407 1.1 christos if (EXTRACTED64(frac_grx, 0, 0) == 0) { 4408 1.1 christos if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_denormalized_number); 4409 1.1 christos if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_denormalized_number); 4410 1.1 christos } 4411 1.1 christos /*Normalize_Operand:*/ 4412 1.1 christos while (EXTRACTED64(frac_grx, 0, 0) == 0) { 4413 1.1 christos exp = exp - 1; 4414 1.1 christos frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51); 4415 1.1 christos } 4416 1.1 christos *frT = (INSERTED64(sign, 0, 0) 4417 1.1 christos | INSERTED64(exp + 1023, 1, 11) 4418 1.1 christos | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63)); 4419 1.1 christos } 4420 1.1 christos GOTO(Done); 4421 1.1 christos /**/ 4422 1.1 christos LABEL(Enabled_Exponent_Underflow): 4423 1.1 christos FPSCR_SET_UX(1); 4424 1.1 christos sign = EXTRACTED64(*frB, 0, 0); 4425 1.1 christos if (EXTRACTED64(*frB, 1, 11) == 0) { 4426 1.1 christos exp = -1022; 4427 1.1 christos frac_grx = INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52); 4428 1.1 christos } 4429 1.1 christos if (EXTRACTED64(*frB, 1, 11) > 0) { 4430 1.1 christos exp = EXTRACTED64(*frB, 1, 11) - 1023; 4431 1.1 christos frac_grx = (BIT64(0) | 4432 1.1 christos INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52)); 4433 1.1 christos } 4434 1.1 christos /*Normalize_Operand:*/ 4435 1.1 christos while (EXTRACTED64(frac_grx, 0, 0) == 0) { 4436 1.1 christos exp = exp - 1; 4437 1.1 christos frac_grx = INSERTED64(EXTRACTED64(frac_grx, 1, 52), 0, 51); 4438 1.1 christos } 4439 1.1 christos Round_Single(processor, sign, &exp, &frac_grx); 4440 1.1 christos FPSCR_SET_XX(FPSCR & fpscr_fi); 4441 1.1 christos exp = exp + 192; 4442 1.1 christos *frT = (INSERTED64(sign, 0, 0) 4443 1.1 christos | INSERTED64(exp + 1023, 1, 11) 4444 1.1 christos | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63)); 4445 1.1 christos if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number); 4446 1.1 christos if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number); 4447 1.1 christos GOTO(Done); 4448 1.1 christos /**/ 4449 1.1 christos LABEL(Disabled_Exponent_Overflow): 4450 1.1 christos FPSCR_SET_OX(1); 4451 1.1 christos if ((FPSCR & fpscr_rn) == fpscr_rn_round_to_nearest) { 4452 1.1 christos if (EXTRACTED64(*frB, 0, 0) == 0) { 4453 1.1 christos *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000; 4454 1.1 christos FPSCR_SET_FPRF(fpscr_rf_pos_infinity); 4455 1.1 christos } 4456 1.1 christos if (EXTRACTED64(*frB, 0, 0) == 1) { 4457 1.1 christos *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000; 4458 1.1 christos FPSCR_SET_FPRF(fpscr_rf_neg_infinity); 4459 1.1 christos } 4460 1.1 christos } 4461 1.1 christos if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_zero) { 4462 1.1 christos if (EXTRACTED64(*frB, 0, 0) == 0) { 4463 1.1 christos *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000; 4464 1.1 christos FPSCR_SET_FPRF(fpscr_rf_pos_normal_number); 4465 1.1 christos } 4466 1.1 christos if (EXTRACTED64(*frB, 0, 0) == 1) { 4467 1.1 christos *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000; 4468 1.1 christos FPSCR_SET_FPRF(fpscr_rf_neg_normal_number); 4469 1.1 christos } 4470 1.1 christos } 4471 1.1 christos if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_pos_infinity) { 4472 1.1 christos if (EXTRACTED64(*frB, 0, 0) == 0) { 4473 1.1 christos *frT = INSERTED64(0x7FF00000, 0, 31) | 0x00000000; 4474 1.1 christos FPSCR_SET_FPRF(fpscr_rf_pos_infinity); 4475 1.1 christos } 4476 1.1 christos if (EXTRACTED64(*frB, 0, 0) == 1) { 4477 1.1 christos *frT = INSERTED64(0xC7EFFFFF, 0, 31) | 0xE0000000; 4478 1.1 christos FPSCR_SET_FPRF(fpscr_rf_neg_normal_number); 4479 1.1 christos } 4480 1.1 christos } 4481 1.1 christos if ((FPSCR & fpscr_rn) == fpscr_rn_round_towards_neg_infinity) { 4482 1.1 christos if (EXTRACTED64(*frB, 0, 0) == 0) { 4483 1.1 christos *frT = INSERTED64(0x47EFFFFF, 0, 31) | 0xE0000000; 4484 1.1 christos FPSCR_SET_FPRF(fpscr_rf_pos_normal_number); 4485 1.1 christos } 4486 1.1 christos if (EXTRACTED64(*frB, 0, 0) == 1) { 4487 1.1 christos *frT = INSERTED64(0xFFF00000, 0, 31) | 0x00000000; 4488 1.1 christos FPSCR_SET_FPRF(fpscr_rf_neg_infinity); 4489 1.1 christos } 4490 1.1 christos } 4491 1.1 christos /* FPSCR[FR] <- undefined */ 4492 1.1 christos FPSCR_SET_FI(1); 4493 1.1 christos FPSCR_SET_XX(1); 4494 1.1 christos GOTO(Done); 4495 1.1 christos /**/ 4496 1.1 christos LABEL(Enabled_Exponent_Overflow): 4497 1.1 christos sign = EXTRACTED64(*frB, 0, 0); 4498 1.1 christos exp = EXTRACTED64(*frB, 1, 11) - 1023; 4499 1.1 christos frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52); 4500 1.1 christos Round_Single(processor, sign, &exp, &frac_grx); 4501 1.1 christos FPSCR_SET_XX(FPSCR & fpscr_fi); 4502 1.1 christos /**/ 4503 1.1 christos LABEL(Enabled_Overflow): 4504 1.1 christos FPSCR_SET_OX(1); 4505 1.1 christos exp = exp - 192; 4506 1.1 christos *frT = (INSERTED64(sign, 0, 0) 4507 1.1 christos | INSERTED64(exp + 1023, 1, 11) 4508 1.1 christos | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63)); 4509 1.1 christos if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number); 4510 1.1 christos if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number); 4511 1.1 christos GOTO(Done); 4512 1.1 christos /**/ 4513 1.1 christos LABEL(Zero_Operand): 4514 1.1 christos *frT = *frB; 4515 1.1 christos if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_zero); 4516 1.1 christos if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_zero); 4517 1.1 christos FPSCR_SET_FR(0); 4518 1.1 christos FPSCR_SET_FI(0); 4519 1.1 christos GOTO(Done); 4520 1.1 christos /**/ 4521 1.1 christos LABEL(Infinity_Operand): 4522 1.1 christos *frT = *frB; 4523 1.1 christos if (EXTRACTED64(*frB, 0, 0) == 0) FPSCR_SET_FPRF(fpscr_rf_pos_infinity); 4524 1.1 christos if (EXTRACTED64(*frB, 0, 0) == 1) FPSCR_SET_FPRF(fpscr_rf_neg_infinity); 4525 1.1 christos FPSCR_SET_FR(0); 4526 1.1 christos FPSCR_SET_FI(0); 4527 1.1 christos GOTO(Done); 4528 1.1 christos /**/ 4529 1.1 christos LABEL(QNaN_Operand): 4530 1.1 christos *frT = INSERTED64(EXTRACTED64(*frB, 0, 34), 0, 34); 4531 1.1 christos FPSCR_SET_FPRF(fpscr_rf_quiet_nan); 4532 1.1 christos FPSCR_SET_FR(0); 4533 1.1 christos FPSCR_SET_FI(0); 4534 1.1 christos GOTO(Done); 4535 1.1 christos /**/ 4536 1.1 christos LABEL(SNaN_Operand): 4537 1.1 christos FPSCR_OR_VX(fpscr_vxsnan); 4538 1.1 christos if ((FPSCR & fpscr_ve) == 0) { 4539 1.1 christos *frT = (MASKED64(*frB, 0, 11) 4540 1.1 christos | BIT64(12) 4541 1.1 christos | MASKED64(*frB, 13, 34)); 4542 1.1 christos FPSCR_SET_FPRF(fpscr_rf_quiet_nan); 4543 1.1 christos } 4544 1.1 christos FPSCR_SET_FR(0); 4545 1.1 christos FPSCR_SET_FI(0); 4546 1.1 christos GOTO(Done); 4547 1.1 christos /**/ 4548 1.1 christos LABEL(Normal_Operand): 4549 1.1 christos sign = EXTRACTED64(*frB, 0, 0); 4550 1.1 christos exp = EXTRACTED64(*frB, 1, 11) - 1023; 4551 1.1 christos frac_grx = BIT64(0) | INSERTED64(EXTRACTED64(*frB, 12, 63), 1, 52); 4552 1.1 christos Round_Single(processor, sign, &exp, &frac_grx); 4553 1.1 christos FPSCR_SET_XX(FPSCR & fpscr_fi); 4554 1.1 christos if (exp > 127 && (FPSCR & fpscr_oe) == 0) GOTO(Disabled_Exponent_Overflow); 4555 1.1 christos if (exp > 127 && (FPSCR & fpscr_oe) != 0) GOTO(Enabled_Overflow); 4556 1.1 christos *frT = (INSERTED64(sign, 0, 0) 4557 1.1 christos | INSERTED64(exp + 1023, 1, 11) 4558 1.1 christos | INSERTED64(EXTRACTED64(frac_grx, 1, 52), 12, 63)); 4559 1.1 christos if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number); 4560 1.1 christos if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_neg_normal_number); 4561 1.1 christos GOTO(Done); 4562 1.1 christos /**/ 4563 1.1 christos LABEL(Done): 4564 1.1 christos PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc); 4565 1.1 christos 4566 1.1 christos 4567 1.1 christos 0.63,6.FRT,11./,16.FRB,21.814,31.Rc:X:64,f::Floating Convert To Integer Doubleword 4568 1.1 christos floating_point_assist_interrupt(processor, cia); 4569 1.1 christos 4570 1.1 christos 0.63,6.FRT,11./,16.FRB,21.815,31.Rc:X:64,f::Floating Convert To Integer Doubleword with round towards Zero 4571 1.1 christos floating_point_assist_interrupt(processor, cia); 4572 1.1 christos 4573 1.1 christos 0.63,6.FRT,11./,16.FRB,21.14,31.Rc:X:f::Floating Convert To Integer Word 4574 1.1 christos floating_point_assist_interrupt(processor, cia); 4575 1.1 christos 4576 1.1 christos 0.63,6.FRT,11./,16.FRB,21.15,31.Rc:X:f:fctiwz:Floating Convert To Integer Word with round towards Zero 4577 1.1 christos *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0 4578 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4579 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4580 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4581 1.1 christos FPSCR_BEGIN; 4582 1.1 christos convert_to_integer(processor, cia, 4583 1.1 christos frT, *frB, 4584 1.1 christos fpscr_rn_round_towards_zero, 32); 4585 1.1 christos FPSCR_END(Rc); 4586 1.1 christos PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc); 4587 1.1 christos 4588 1.1 christos 0.63,6.FRT,11./,16.FRB,21.846,31.Rc:X:64,f::Floating Convert from Integer Doubleword 4589 1.1 christos int sign = EXTRACTED64(*frB, 0, 0); 4590 1.1 christos int exp = 63; 4591 1.1 christos uint64_t frac = *frB; 4592 1.1 christos /***/ 4593 1.1 christos if (frac == 0) GOTO(Zero_Operand); 4594 1.1 christos if (sign == 1) frac = ~frac + 1; 4595 1.1 christos while (EXTRACTED64(frac, 0, 0) == 0) { 4596 1.1 christos /*??? do the loop 0 times if (FRB) = max negative integer */ 4597 1.1 christos frac = INSERTED64(EXTRACTED64(frac, 1, 63), 0, 62); 4598 1.1 christos exp = exp - 1; 4599 1.1 christos } 4600 1.1 christos Round_Float(processor, sign, &exp, &frac, FPSCR & fpscr_rn); 4601 1.1 christos if (sign == 0) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number); 4602 1.1 christos if (sign == 1) FPSCR_SET_FPRF(fpscr_rf_pos_normal_number); 4603 1.1 christos *frT = (INSERTED64(sign, 0, 0) 4604 1.1 christos | INSERTED64(exp + 1023, 1, 11) 4605 1.1 christos | INSERTED64(EXTRACTED64(frac, 1, 52), 12, 63)); 4606 1.1 christos GOTO(Done); 4607 1.1 christos /**/ 4608 1.1 christos LABEL(Zero_Operand): 4609 1.1 christos FPSCR_SET_FR(0); 4610 1.1 christos FPSCR_SET_FI(0); 4611 1.1 christos FPSCR_SET_FPRF(fpscr_rf_pos_zero); 4612 1.1 christos *frT = 0; 4613 1.1 christos GOTO(Done); 4614 1.1 christos /**/ 4615 1.1 christos LABEL(Done): 4616 1.1 christos PPC_INSN_FLOAT(FRT_BITMASK, FRB_BITMASK, Rc); 4617 1.1 christos 4618 1.1 christos 4619 1.1 christos # 4620 1.1 christos # I.4.6.7 Floating-Point Compare Instructions 4621 1.1 christos # 4622 1.1 christos 4623 1.1 christos 0.63,6.BF,9./,11.FRA,16.FRB,21.0,31./:X:f:fcmpu:Floating Compare Unordered 4624 1.1 christos *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0 4625 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4626 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4627 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4628 1.1 christos FPSCR_BEGIN; 4629 1.1 christos unsigned c; 4630 1.1 christos if (is_NaN(*frA, 0) || is_NaN(*frB, 0)) 4631 1.1 christos c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */ 4632 1.1 christos else if (is_less_than(frA, frB)) 4633 1.1 christos c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */ 4634 1.1 christos else if (is_greater_than(frA, frB)) 4635 1.1 christos c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */ 4636 1.1 christos else 4637 1.1 christos c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */ 4638 1.1 christos FPSCR_SET_FPCC(c); 4639 1.1 christos CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */ 4640 1.1 christos if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) 4641 1.1 christos FPSCR_OR_VX(fpscr_vxsnan); 4642 1.1 christos FPSCR_END(0); 4643 1.1 christos PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK); 4644 1.1 christos 4645 1.1 christos 0.63,6.BF,9./,11.FRA,16.FRB,21.32,31./:X:f:fcmpo:Floating Compare Ordered 4646 1.1 christos *601: PPC_UNIT_FPU, PPC_UNIT_FPU, 4, 4, 0 4647 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4648 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4649 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4650 1.1 christos FPSCR_BEGIN; 4651 1.1 christos unsigned c; 4652 1.1 christos if (is_NaN(*frA, 0) || is_NaN(*frB, 0)) 4653 1.1 christos c = cr_i_summary_overflow; /* 0b0001 - (FRA) ? (FRB) */ 4654 1.1 christos else if (is_less_than(frA, frB)) 4655 1.1 christos c = cr_i_negative; /* 0b1000 - (FRA) < (FRB) */ 4656 1.1 christos else if (is_greater_than(frA, frB)) 4657 1.1 christos c = cr_i_positive; /* 0b0100 - (FRA) > (FRB) */ 4658 1.1 christos else 4659 1.1 christos c = cr_i_zero; /* 0b0010 - (FRA) = (FRB) */ 4660 1.1 christos FPSCR_SET_FPCC(c); 4661 1.1 christos CR_SET(BF, c); /* CR[4*BF..4*BF+3] = c */ 4662 1.1 christos if (is_SNaN(*frA, 0) || is_SNaN(*frB, 0)) { 4663 1.1 christos FPSCR_OR_VX(fpscr_vxsnan); 4664 1.1 christos if ((FPSCR & fpscr_ve) == 0) 4665 1.1 christos FPSCR_OR_VX(fpscr_vxvc); 4666 1.1 christos } 4667 1.1 christos else if (is_QNaN(*frA, 0) || is_QNaN(*frB, 0)) { 4668 1.1 christos FPSCR_OR_VX(fpscr_vxvc); 4669 1.1 christos } 4670 1.1 christos FPSCR_END(0); 4671 1.1 christos PPC_INSN_FLOAT_CR(0, FRA_BITMASK | FRB_BITMASK, BF_BITMASK); 4672 1.1 christos 4673 1.1 christos 4674 1.1 christos # 4675 1.1 christos # I.4.6.8 Floating-Point Status and Control Register Instructions 4676 1.1 christos # 4677 1.1 christos 4678 1.1 christos 0.63,6.FRT,11./,16./,21.583,31.Rc:X:f::Move From FPSCR 4679 1.1 christos FPSCR_BEGIN; 4680 1.1 christos *frT = FPSCR; 4681 1.1 christos FPSCR_END(Rc); 4682 1.1 christos 4683 1.1 christos 0.63,6.BF,9./,11.BFA,14./,16./,21.64,31./:X:f::Move to Condition Register from FPSCR 4684 1.1 christos FPSCR_BEGIN; 4685 1.1 christos unsigned field = FPSCR_FIELD(BFA); 4686 1.1 christos CR_SET(BF, field); 4687 1.1 christos FPSCR_SET(BFA, 0); /* FPSCR_END fixes up FEX/VX */ 4688 1.1 christos FPSCR_END(0); 4689 1.1 christos 4690 1.1 christos 0.63,6.BF,9./,11./,16.U,20./,21.134,31.Rc:X:f::Move To FPSCR Field Immediate 4691 1.1 christos FPSCR_BEGIN; 4692 1.1 christos FPSCR_SET(BF, U); 4693 1.1 christos FPSCR_END(Rc); 4694 1.1 christos 4695 1.1 christos 0.63,6./,7.FLM,15./,16.FRB,21.711,31.Rc:XFL:f::Move To FPSCR Fields 4696 1.1 christos FPSCR_BEGIN; 4697 1.1 christos int i; 4698 1.1 christos for (i = 0; i < 8; i++) { 4699 1.1 christos if ((FLM & BIT8(i))) { 4700 1.1 christos FPSCR &= ~MASK32(i*4, i*4+3); 4701 1.1 christos FPSCR |= MASKED32(*frB, i*4, i*4+3); 4702 1.1 christos } 4703 1.1 christos } 4704 1.1 christos FPSCR_END(Rc); 4705 1.1 christos 4706 1.1 christos 0.63,6.BT,11./,16./,21.70,31.Rc:X:f::Move To FPSCR Bit 0 4707 1.1 christos FPSCR_BEGIN; 4708 1.1 christos uint32_t bit = BIT32(BT); 4709 1.1 christos FPSCR &= ~bit; 4710 1.1 christos FPSCR_END(Rc); 4711 1.1 christos 4712 1.1 christos 0.63,6.BT,11./,16./,21.38,31.Rc:X:f::Move To FPSCR Bit 1 4713 1.1 christos FPSCR_BEGIN; 4714 1.1 christos uint32_t bit = BIT32(BT); 4715 1.1 christos if (bit & fpscr_fi) 4716 1.1 christos bit |= fpscr_xx; 4717 1.1 christos if ((bit & fpscr_vx_bits)) 4718 1.1 christos bit |= fpscr_fx; 4719 1.1 christos /* note - omit vx bit */ 4720 1.1 christos if ((bit & (fpscr_ox | fpscr_ux | fpscr_zx | fpscr_xx))) 4721 1.1 christos bit |= fpscr_fx; 4722 1.1 christos FPSCR |= bit; 4723 1.1 christos FPSCR_END(Rc); 4724 1.1 christos 4725 1.1 christos # 4726 1.1 christos # I.A.1.2 Floating-Point Arithmetic Instructions 4727 1.1 christos # 4728 1.1 christos 4729 1.1 christos 0.63,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f,o::Floating Square Root 4730 1.1 christos program_interrupt(processor, cia, optional_instruction_program_interrupt); 4731 1.1 christos 4732 1.1 christos 0.59,6.FRT,11./,16.FRB,21./,26.22,31.Rc:A:f,o::Floating Square Root Single 4733 1.1 christos program_interrupt(processor, cia, optional_instruction_program_interrupt); 4734 1.1 christos 4735 1.1 christos 0.59,6.FRT,11./,16.FRB,21./,26.24,31.Rc:A:f,o::Floating Reciprocal Estimate Single 4736 1.1 christos program_interrupt(processor, cia, optional_instruction_program_interrupt); 4737 1.1 christos 4738 1.1 christos 0.63,6.FRT,11./,16.FRB,21./,26.26,31.Rc:A:f,o::Floating Reciprocal Square Root Estimate 4739 1.1 christos program_interrupt(processor, cia, optional_instruction_program_interrupt); 4740 1.1 christos 4741 1.1 christos # 4742 1.1 christos # I.A.1.3 Floating-Point Select Instruction 4743 1.1 christos # 4744 1.1 christos 4745 1.1 christos 0.63,6.FRT,11.FRA,16.FRB,21.FRC,26.23,31.Rc:A:f,o::Floating Select 4746 1.1 christos *601: PPC_UNIT_BAD, PPC_UNIT_BAD, 0, 0, 0 4747 1.1 christos *603: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4748 1.1 christos *603e:PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4749 1.1 christos *604: PPC_UNIT_FPU, PPC_UNIT_FPU, 1, 3, 0 4750 1.1 christos if (CURRENT_MODEL == MODEL_ppc601) { 4751 1.1 christos program_interrupt(processor, cia, optional_instruction_program_interrupt); 4752 1.1 christos } else { 4753 1.1 christos uint64_t zero = 0; 4754 1.1 christos FPSCR_BEGIN; 4755 1.1 christos if (is_NaN(*frA, 0) || is_less_than (frA, &zero)) *frT = *frB; 4756 1.1 christos else *frT = *frC; 4757 1.1 christos FPSCR_END(Rc); 4758 1.1 christos PPC_INSN_FLOAT(FRT_BITMASK, FRA_BITMASK | FRB_BITMASK | FRC_BITMASK, Rc); 4759 1.1 christos } 4760 1.1 christos 4761 1.1 christos # 4762 1.1 christos # II.3.2 Cache Management Instructions 4763 1.1 christos # 4764 1.1 christos 4765 1.1 christos 0.31,6./,11.RA,16.RB,21.982,31./:X::icbi:Instruction Cache Block Invalidate 4766 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 4767 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 4768 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 4769 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0 4770 1.1 christos /* blindly flush all instruction cache entries */ 4771 1.1 christos #if WITH_IDECODE_CACHE_SIZE 4772 1.1 christos cpu_flush_icache(processor); 4773 1.1 christos #endif 4774 1.1 christos PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0); 4775 1.1 christos 4776 1.1 christos 0.19,6./,11./,16./,21.150,31./:XL::isync:Instruction Synchronize 4777 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 4778 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 4779 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 4780 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0 4781 1.1 christos cpu_synchronize_context(processor, cia); 4782 1.1 christos PPC_INSN_INT(0, 0, 0); 4783 1.1 christos 4784 1.1 christos 4785 1.1 christos # 4786 1.1 christos # II.3.2.2 Data Cache Instructions 4787 1.1 christos # 4788 1.1 christos 4789 1.1 christos 0.31,6./,11.RA,16.RB,21.278,31./:X:::Data Cache Block Touch 4790 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 4791 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0 4792 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0 4793 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0 4794 1.1 christos TRACE(trace_tbd,("Data Cache Block Touch\n")); 4795 1.1 christos PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/); 4796 1.1 christos 4797 1.1 christos 0.31,6./,11.RA,16.RB,21.246,31./:X:::Data Cache Block Touch for Store 4798 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 4799 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0 4800 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0 4801 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 4802 1.1 christos TRACE(trace_tbd,("Data Cache Block Touch for Store\n")); 4803 1.1 christos PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/); 4804 1.1 christos 4805 1.1 christos 0.31,6./,11.RA,16.RB,21.1014,31./:X:::Data Cache Block set to Zero 4806 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 4807 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0 4808 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 10, 10, 0 4809 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 4810 1.1 christos TRACE(trace_tbd,("Data Cache Block set to Zero\n")); 4811 1.1 christos PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/); 4812 1.1 christos 4813 1.1 christos 0.31,6./,11.RA,16.RB,21.54,31./:X:::Data Cache Block Store 4814 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 4815 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0 4816 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0 4817 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0 4818 1.1 christos TRACE(trace_tbd,("Data Cache Block Store\n")); 4819 1.1 christos PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/); 4820 1.1 christos 4821 1.1 christos 0.31,6./,11.RA,16.RB,21.86,31./:X:::Data Cache Block Flush 4822 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 4823 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0 4824 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 5, 5, 0 4825 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 1, 0 4826 1.1 christos TRACE(trace_tbd,("Data Cache Block Flush\n")); 4827 1.1 christos PPC_INSN_INT(0, (RA_BITMASK & ~1) | RB_BITMASK, 0/*Rc*/); 4828 1.1 christos 4829 1.1 christos # 4830 1.1 christos # II.3.3 Enforce In-order Execution of I/O Instruction 4831 1.1 christos # 4832 1.1 christos 4833 1.1 christos 0.31,6./,11./,16./,21.854,31./:X::eieio:Enforce In-order Execution of I/O 4834 1.1 christos /* Since this model has no instruction overlap 4835 1.1 christos this instruction need do nothing */ 4836 1.1 christos 4837 1.1 christos # 4838 1.1 christos # II.4.1 Time Base Instructions 4839 1.1 christos # 4840 1.1 christos 4841 1.1 christos 0.31,6.RT,11.tbr,21.371,31./:XFX::mftb:Move From Time Base 4842 1.1 christos *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 4843 1.1 christos *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 4844 1.1 christos *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0 4845 1.1 christos int n = (tbr{5:9} << 5) | tbr{0:4}; 4846 1.1 christos if (n == 268) { 4847 1.1 christos if (is_64bit_implementation) *rT = TB; 4848 1.1 christos else *rT = EXTRACTED64(TB, 32, 63); 4849 1.1 christos } 4850 1.1 christos else if (n == 269) { 4851 1.1 christos if (is_64bit_implementation) *rT = EXTRACTED64(TB, 0, 31); 4852 1.1 christos else *rT = EXTRACTED64(TB, 0, 31); 4853 1.1 christos } 4854 1.1 christos else 4855 1.1 christos program_interrupt(processor, cia, 4856 1.1 christos illegal_instruction_program_interrupt); 4857 1.1 christos 4858 1.1 christos 4859 1.1 christos # 4860 1.1 christos # III.2.3.1 System Linkage Instructions 4861 1.1 christos # 4862 1.1 christos 4863 1.1 christos 0.19,6./,11./,16./,21.50,31./:XL::rfi:Return From Interrupt 4864 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 4865 1.1 christos *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0 4866 1.1 christos *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0 4867 1.1 christos *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0 4868 1.1 christos if (IS_PROBLEM_STATE(processor)) { 4869 1.1 christos program_interrupt(processor, cia, 4870 1.1 christos privileged_instruction_program_interrupt); 4871 1.1 christos } 4872 1.1 christos else { 4873 1.1 christos MSR = (MASKED(SRR1, 0, 32) 4874 1.1 christos | MASKED(SRR1, 37, 41) 4875 1.1 christos | MASKED(SRR1, 48, 63)); 4876 1.1 christos NIA = MASKED(SRR0, 0, 61); 4877 1.1 christos cpu_synchronize_context(processor, cia); 4878 1.1 christos check_masked_interrupts(processor); 4879 1.1 christos } 4880 1.1 christos 4881 1.1 christos # 4882 1.1 christos # III.3.4.1 Move to/from System Register Instructions 4883 1.1 christos # 4884 1.1 christos 4885 1.1 christos #0.31,6.RS,11.SPR,21.467,31./:XFX:::Move To Special Purpose Register 4886 1.1 christos #0.31,6.RT,11.SPR,21.339,31./:XFX:::Move From Special Purpose Register 4887 1.1 christos 0.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register 4888 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 4889 1.1 christos *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0 4890 1.1 christos *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0 4891 1.1 christos *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0 4892 1.1 christos if (IS_PROBLEM_STATE(processor)) 4893 1.1 christos program_interrupt(processor, cia, 4894 1.1 christos privileged_instruction_program_interrupt); 4895 1.1 christos else { 4896 1.1 christos MSR = *rS; 4897 1.1 christos check_masked_interrupts(processor); 4898 1.1 christos } 4899 1.1 christos 4900 1.1 christos 0.31,6.RT,11./,16./,21.83,31./:X:::Move From Machine State Register 4901 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 4902 1.1 christos *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 4903 1.1 christos *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0 4904 1.1 christos *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 3, 3, 0 4905 1.1 christos if (IS_PROBLEM_STATE(processor)) 4906 1.1 christos program_interrupt(processor, cia, 4907 1.1 christos privileged_instruction_program_interrupt); 4908 1.1 christos else { 4909 1.1 christos *rT = MSR; 4910 1.1 christos check_masked_interrupts(processor); 4911 1.1 christos } 4912 1.1 christos 4913 1.1 christos 4914 1.1 christos # 4915 1.1 christos # III.4.11.1 Cache Management Instructions 4916 1.1 christos # 4917 1.1 christos 4918 1.1 christos 0.31,6./,11.RA,16.RB,21.470,31./:X::dcbi:Data Cache Block Invalidate 4919 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 4920 1.1 christos *603: PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0 4921 1.1 christos *603e:PPC_UNIT_LSU, PPC_UNIT_LSU, 2, 2, 0 4922 1.1 christos *604: PPC_UNIT_LSU, PPC_UNIT_LSU, 1, 3, 0 4923 1.1 christos if (IS_PROBLEM_STATE(processor)) 4924 1.1 christos program_interrupt(processor, cia, 4925 1.1 christos privileged_instruction_program_interrupt); 4926 1.1 christos else 4927 1.1 christos TRACE(trace_tbd,("Data Cache Block Invalidate\n")); 4928 1.1 christos 4929 1.1 christos # 4930 1.1 christos # III.4.11.2 Segment Register Manipulation Instructions 4931 1.1 christos # 4932 1.1 christos 4933 1.1 christos 0.31,6.RS,11./,12.SR,16./,21.210,31./:X:32:mtsr %SR,%RS:Move To Segment Register 4934 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 4935 1.1 christos *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0 4936 1.1 christos *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0 4937 1.1 christos *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0 4938 1.1 christos if (IS_PROBLEM_STATE(processor)) 4939 1.1 christos program_interrupt(processor, cia, 4940 1.1 christos privileged_instruction_program_interrupt); 4941 1.1 christos else 4942 1.1 christos SEGREG(SR) = *rS; 4943 1.1 christos 4944 1.1 christos 0.31,6.RS,11./,16.RB,21.242,31./:X:32:mtsrin %RS,%RB:Move To Segment Register Indirect 4945 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0 4946 1.1 christos *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0 4947 1.1 christos *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 2, 2, 0 4948 1.1 christos *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0 4949 1.1 christos if (IS_PROBLEM_STATE(processor)) 4950 1.1 christos program_interrupt(processor, cia, 4951 1.1 christos privileged_instruction_program_interrupt); 4952 1.1 christos else 4953 1.1 christos SEGREG(EXTRACTED32(*rB, 0, 3)) = *rS; 4954 1.1 christos 4955 1.1 christos 0.31,6.RT,11./,12.SR,16./,21.595,31./:X:32:mfsr %RT,%RS:Move From Segment Register 4956 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0 4957 1.1 christos *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0 4958 1.1 christos *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0 4959 1.1 christos *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0 4960 1.1 christos if (IS_PROBLEM_STATE(processor)) 4961 1.1 christos program_interrupt(processor, cia, 4962 1.1 christos privileged_instruction_program_interrupt); 4963 1.1 christos else 4964 1.1 christos *rT = SEGREG(SR); 4965 1.1 christos 4966 1.1 christos 0.31,6.RT,11./,16.RB,21.659,31./:X:32:mfsrin %RT,%RB:Move From Segment Register Indirect 4967 1.1 christos *601: PPC_UNIT_IU, PPC_UNIT_IU, 2, 2, 0 4968 1.1 christos *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0 4969 1.1 christos *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0 4970 1.1 christos *604: PPC_UNIT_MCIU, PPC_UNIT_MCIU, 1, 1, 0 4971 1.1 christos if (IS_PROBLEM_STATE(processor)) 4972 1.1 christos program_interrupt(processor, cia, 4973 1.1 christos privileged_instruction_program_interrupt); 4974 1.1 christos else 4975 1.1 christos *rT = SEGREG(EXTRACTED32(*rB, 0, 3)); 4976 1.1 christos 4977 1.1 christos 4978 1.1 christos # 4979 1.1 christos # III.4.11.3 Lookaside Buffer Management Instructions (Optional) 4980 1.1 christos # 4981 1.1 christos 4982 1.1 christos 0.31,6./,11./,16.RB,21.434,31./:X:64::SLB Invalidate Entry 4983 1.1 christos 4984 1.1 christos 0.31,6./,11./,16./,21.498,31./:X:64::SLB Invalidate All 4985 1.1 christos 4986 1.1 christos 0.31,6./,11./,16.RB,21.306,31./:X:::TLB Invalidate Entry 4987 1.1 christos if (IS_PROBLEM_STATE(processor)) 4988 1.1 christos program_interrupt(processor, cia, 4989 1.1 christos privileged_instruction_program_interrupt); 4990 1.1 christos else { 4991 1.1 christos int nr = 0; 4992 1.1 christos cpu *proc; 4993 1.1 christos while (1) { 4994 1.1 christos proc = psim_cpu(cpu_system(processor), nr); 4995 1.1 christos if (proc == NULL) break; 4996 1.1 christos cpu_page_tlb_invalidate_entry(proc, *rB); 4997 1.1 christos nr++; 4998 1.1 christos } 4999 1.1 christos } 5000 1.1 christos 5001 1.1 christos 0.31,6./,11./,16./,21.370,31./:X:::TLB Invalidate All 5002 1.1 christos if (IS_PROBLEM_STATE(processor)) 5003 1.1 christos program_interrupt(processor, cia, 5004 1.1 christos privileged_instruction_program_interrupt); 5005 1.1 christos else { 5006 1.1 christos int nr = 0; 5007 1.1 christos cpu *proc; 5008 1.1 christos while (1) { 5009 1.1 christos proc = psim_cpu(cpu_system(processor), nr); 5010 1.1 christos if (proc == NULL) break; 5011 1.1 christos cpu_page_tlb_invalidate_all(proc); 5012 1.1 christos nr++; 5013 1.1 christos } 5014 1.1 christos } 5015 1.1 christos 5016 1.1 christos 0.31,6./,11./,16./,21.566,31./:X:::TLB Synchronize 5017 1.1 christos /* nothing happens here - always in sync */ 5018 1.1 christos 5019 1.1 christos # 5020 1.1 christos # III.A.1.2 External Access Instructions 5021 1.1 christos # 5022 1.1 christos 5023 0.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed 5024 5025 0.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed 5026 5027 :include:::altivec.igen 5028 :include:::e500.igen 5029