Skip to content

Commit 564c43c

Browse files
committed
Remove ppc_cur_instruction global variable
Replace it wth an explicit opcode parameter that is passed around. That is both slightly easier to reason about (to trace where it comes from) and slightly faster, since it can be read from a register. On my machine takes booting to "Welcome to Macintosh" being output in a verbose boot of Mac OS X 10.2.8 from 31.8s to 30.6s (average of 5 runs, measured using deterministic mode and looking at when execution reaches PC 0x90004a88).
1 parent 31bc6f7 commit 564c43c

11 files changed

Lines changed: 1093 additions & 1090 deletions

File tree

cpu/ppc/poweropcodes.cpp

Lines changed: 122 additions & 122 deletions
Large diffs are not rendered by default.

cpu/ppc/ppcemu.h

Lines changed: 202 additions & 203 deletions
Large diffs are not rendered by default.

cpu/ppc/ppcexceptions.cpp

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -196,17 +196,17 @@ void ppc_exception_handler(Except_Type exception_type, uint32_t srr1_bits) {
196196
throw std::invalid_argument(exc_descriptor);
197197
}
198198

199-
void ppc_floating_point_exception() {
199+
void ppc_floating_point_exception(uint32_t opcode) {
200200
LOG_F(ERROR, "Floating point exception at 0x%08x for instruction 0x%08x",
201-
ppc_state.pc, ppc_cur_instruction);
201+
ppc_state.pc, opcode);
202202
// mmu_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::FPU_EXCEPTION);
203203
}
204204

205-
void ppc_alignment_exception(uint32_t ea)
205+
void ppc_alignment_exception(uint32_t opcode, uint32_t ea)
206206
{
207207
uint32_t dsisr;
208208

209-
switch (ppc_cur_instruction & 0xfc000000) {
209+
switch (opcode & 0xfc000000) {
210210
case 0x80000000: // lwz
211211
case 0x90000000: // stw
212212
case 0xa0000000: // lhz
@@ -228,11 +228,11 @@ void ppc_alignment_exception(uint32_t ea)
228228
case 0xd4000000: // stfsu
229229
case 0xdc000000: // stfdu
230230
// indirect with immediate index
231-
dsisr = ((ppc_cur_instruction >> 12) & 0x00004000) // bit 17 — Set to bit 5 of the instruction.
232-
| ((ppc_cur_instruction >> 17) & 0x00003c00); // bits 18–21 - set to bits 1–4 of the instruction.
231+
dsisr = ((opcode >> 12) & 0x00004000) // bit 17 — Set to bit 5 of the instruction.
232+
| ((opcode >> 17) & 0x00003c00); // bits 18–21 - set to bits 1–4 of the instruction.
233233
break;
234234
case 0x7c000000:
235-
switch (ppc_cur_instruction & 0xfc0007ff) {
235+
switch (opcode & 0xfc0007ff) {
236236
case 0x7c000028: // lwarx (invalid form - bits 15-21 of DSISR are identical to those of lwz)
237237
case 0x7c0002aa: // lwax (64-bit only)
238238
case 0x7c00042a: // lswx
@@ -266,12 +266,12 @@ void ppc_alignment_exception(uint32_t ea)
266266
case 0x7c00056e: // stfsux
267267
case 0x7c0005ee: // stfdux
268268
indirect_with_index:
269-
dsisr = ((ppc_cur_instruction << 14) & 0x00018000) // bits 15–16 - set to bits 29–30 of the instruction.
270-
| ((ppc_cur_instruction << 8) & 0x00004000) // bit 17 - set to bit 25 of the instruction.
271-
| ((ppc_cur_instruction << 3) & 0x00003c00); // bits 18–21 - set to bits 21–24 of the instruction.
269+
dsisr = ((opcode << 14) & 0x00018000) // bits 15–16 - set to bits 29–30 of the instruction.
270+
| ((opcode << 8) & 0x00004000) // bit 17 - set to bit 25 of the instruction.
271+
| ((opcode << 3) & 0x00003c00); // bits 18–21 - set to bits 21–24 of the instruction.
272272
break;
273273
case 0x7c0007ec:
274-
if ((ppc_cur_instruction & 0xffe007ff) == 0x7c0007ec) // dcbz
274+
if ((opcode & 0xffe007ff) == 0x7c0007ec) // dcbz
275275
goto indirect_with_index;
276276
/* fallthrough */
277277
default:
@@ -282,31 +282,31 @@ void ppc_alignment_exception(uint32_t ea)
282282
unexpected_instruction:
283283
dsisr = 0;
284284
LOG_F(ERROR, "Alignment exception from unexpected instruction 0x%08x",
285-
ppc_cur_instruction);
285+
opcode);
286286
}
287287

288288
// bits 22–26 - Set to bits 6–10 (source or destination) of the instruction.
289289
// Undefined for dcbz.
290-
dsisr |= ((ppc_cur_instruction >> 16) & 0x000003e0);
290+
dsisr |= ((opcode >> 16) & 0x000003e0);
291291

292-
if ((ppc_cur_instruction & 0xfc000000) == 0xb8000000) { // lmw
292+
if ((opcode & 0xfc000000) == 0xb8000000) { // lmw
293293
LOG_F(ERROR, "Alignment exception from instruction 0x%08x (lmw). "
294-
"What to set DSISR bits 27-31?", ppc_cur_instruction);
295-
// dsisr |= ((ppc_cur_instruction >> ?) & 0x0000001f); // bits 27–31
294+
"What to set DSISR bits 27-31?", opcode);
295+
// dsisr |= ((opcode >> ?) & 0x0000001f); // bits 27–31
296296
}
297-
else if ((ppc_cur_instruction & 0xfc0007ff) == 0x7c0004aa) { // lswi
297+
else if ((opcode & 0xfc0007ff) == 0x7c0004aa) { // lswi
298298
LOG_F(ERROR, "Alignment exception from instruction 0x%08x (lswi). "
299-
"What to set DSISR bits 27-31?", ppc_cur_instruction);
300-
// dsisr |= ((ppc_cur_instruction >> ?) & 0x0000001f); // bits 27–31
299+
"What to set DSISR bits 27-31?", opcode);
300+
// dsisr |= ((opcode >> ?) & 0x0000001f); // bits 27–31
301301
}
302-
else if ((ppc_cur_instruction & 0xfc0007ff) == 0x7c00042a) { // lswx
302+
else if ((opcode & 0xfc0007ff) == 0x7c00042a) { // lswx
303303
LOG_F(ERROR, "Alignment exception from instruction 0x%08x (lswx). "
304-
"What to set DSISR bits 27-31?", ppc_cur_instruction);
305-
// dsisr |= ((ppc_cur_instruction >> ?) & 0x0000001f); // bits 27–31
304+
"What to set DSISR bits 27-31?", opcode);
305+
// dsisr |= ((opcode >> ?) & 0x0000001f); // bits 27–31
306306
}
307307
else {
308308
// bits 27–31 - Set to bits 11–15 of the instruction (rA)
309-
dsisr |= ((ppc_cur_instruction >> 16) & 0x0000001f);
309+
dsisr |= ((opcode >> 16) & 0x0000001f);
310310
}
311311

312312
ppc_state.spr[SPR::DSISR] = dsisr;

cpu/ppc/ppcexec.cpp

Lines changed: 58 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ Po_Cause power_off_reason = po_enter_debugger;
6565

6666
SetPRS ppc_state;
6767

68-
uint32_t ppc_cur_instruction; // Current instruction for the PPC
6968
uint32_t ppc_next_instruction_address; // Used for branching, setting up the NIA
7069

7170
unsigned exec_flags; // execution control flags
@@ -208,7 +207,7 @@ static PPCOpcode SubOpcode63Grabber[2048];
208207

209208
/** Exception helpers. */
210209

211-
void ppc_illegalop() {
210+
void ppc_illegalop(uint32_t opcode) {
212211
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
213212
}
214213

@@ -228,97 +227,97 @@ void ppc_release_int() {
228227

229228
/** Opcode decoding functions. */
230229

231-
static void ppc_opcode16() {
232-
SubOpcode16Grabber[ppc_cur_instruction & 3]();
230+
static void ppc_opcode16(uint32_t opcode) {
231+
SubOpcode16Grabber[opcode & 3](opcode);
233232
}
234233

235-
static void ppc_opcode18() {
236-
SubOpcode18Grabber[ppc_cur_instruction & 3]();
234+
static void ppc_opcode18(uint32_t opcode) {
235+
SubOpcode18Grabber[opcode & 3](opcode);
237236
}
238237

239238
template<field_601 for601>
240-
static void ppc_opcode19() {
241-
uint16_t subop_grab = ppc_cur_instruction & 0x7FF;
239+
static void ppc_opcode19(uint32_t opcode) {
240+
uint16_t subop_grab = opcode & 0x7FF;
242241

243242
switch (subop_grab) {
244243
case 0:
245-
ppc_mcrf();
244+
ppc_mcrf(opcode);
246245
break;
247246
case 32:
248-
ppc_bclr<LK0>();
247+
ppc_bclr<LK0>(opcode);
249248
break;
250249
case 33:
251-
ppc_bclr<LK1>();
250+
ppc_bclr<LK1>(opcode);
252251
break;
253252
case 66:
254-
ppc_crnor();
253+
ppc_crnor(opcode);
255254
break;
256255
case 100:
257-
ppc_rfi();
256+
ppc_rfi(opcode);
258257
break;
259258
case 258:
260-
ppc_crandc();
259+
ppc_crandc(opcode);
261260
break;
262261
case 300:
263-
ppc_isync();
262+
ppc_isync(opcode);
264263
break;
265264
case 386:
266-
ppc_crxor();
265+
ppc_crxor(opcode);
267266
break;
268267
case 450:
269-
ppc_crnand();
268+
ppc_crnand(opcode);
270269
break;
271270
case 514:
272-
ppc_crand();
271+
ppc_crand(opcode);
273272
break;
274273
case 578:
275-
ppc_creqv();
274+
ppc_creqv(opcode);
276275
break;
277276
case 834:
278-
ppc_crorc();
277+
ppc_crorc(opcode);
279278
break;
280279
case 898:
281-
ppc_cror();
280+
ppc_cror(opcode);
282281
break;
283282
case 1056:
284-
ppc_bcctr<LK0, for601>();
283+
ppc_bcctr<LK0, for601>(opcode);
285284
break;
286285
case 1057:
287-
ppc_bcctr<LK1, for601>();
286+
ppc_bcctr<LK1, for601>(opcode);
288287
break;
289288
default:
290-
ppc_illegalop();
289+
ppc_illegalop(opcode);
291290
}
292291
}
293292

294-
template void ppc_opcode19<NOT601>();
295-
template void ppc_opcode19<IS601>();
293+
template void ppc_opcode19<NOT601>(uint32_t opcode);
294+
template void ppc_opcode19<IS601>(uint32_t opcode);
296295

297-
static void ppc_opcode31() {
298-
uint16_t subop_grab = ppc_cur_instruction & 0x7FFUL;
299-
SubOpcode31Grabber[subop_grab]();
296+
static void ppc_opcode31(uint32_t opcode) {
297+
uint16_t subop_grab = opcode & 0x7FFUL;
298+
SubOpcode31Grabber[subop_grab](opcode);
300299
}
301300

302-
static void ppc_opcode59() {
303-
uint16_t subop_grab = ppc_cur_instruction & 0x3FUL;
304-
SubOpcode59Grabber[subop_grab]();
301+
static void ppc_opcode59(uint32_t opcode) {
302+
uint16_t subop_grab = opcode & 0x3FUL;
303+
SubOpcode59Grabber[subop_grab](opcode);
305304
}
306305

307-
static void ppc_opcode63() {
308-
uint16_t subop_grab = ppc_cur_instruction & 0x7FFUL;
309-
SubOpcode63Grabber[subop_grab]();
306+
static void ppc_opcode63(uint32_t opcode) {
307+
uint16_t subop_grab = opcode & 0x7FFUL;
308+
SubOpcode63Grabber[subop_grab](opcode);
310309
}
311310

312311
/* Dispatch using main opcode */
313-
void ppc_main_opcode()
312+
void ppc_main_opcode(uint32_t opcode)
314313
{
315314
#ifdef CPU_PROFILING
316315
num_executed_instrs++;
317316
#if defined(CPU_PROFILING_OPS)
318-
num_opcodes[ppc_cur_instruction]++;
317+
num_opcodes[opcode]++;
319318
#endif
320319
#endif
321-
OpcodeGrabber[(ppc_cur_instruction >> 26) & 0x3F]();
320+
OpcodeGrabber[(opcode >> 26) & 0x3F](opcode);
322321
}
323322

324323
static long long cpu_now_ns() {
@@ -363,6 +362,7 @@ static void ppc_exec_inner()
363362
{
364363
uint64_t max_cycles;
365364
uint32_t page_start, eb_start, eb_end;
365+
uint32_t opcode;
366366
uint8_t* pc_real;
367367

368368
max_cycles = 0;
@@ -376,10 +376,11 @@ static void ppc_exec_inner()
376376
exec_flags = 0;
377377

378378
pc_real = mmu_translate_imem(eb_start);
379+
opcode = ppc_read_instruction(pc_real);
379380

380381
// interpret execution block
381382
while (power_on && ppc_state.pc < eb_end) {
382-
ppc_main_opcode();
383+
ppc_main_opcode(opcode);
383384
if (g_icycles++ >= max_cycles || exec_timer) {
384385
max_cycles = process_events();
385386
}
@@ -389,18 +390,19 @@ static void ppc_exec_inner()
389390
eb_start = ppc_next_instruction_address;
390391
if (!(exec_flags & EXEF_RFI) && (eb_start & PPC_PAGE_MASK) == page_start) {
391392
pc_real += (int)eb_start - (int)ppc_state.pc;
392-
ppc_set_cur_instruction(pc_real);
393+
opcode = ppc_read_instruction(pc_real);
393394
} else {
394395
page_start = eb_start & PPC_PAGE_MASK;
395396
eb_end = page_start + PPC_PAGE_SIZE - 1;
396397
pc_real = mmu_translate_imem(eb_start);
398+
opcode = ppc_read_instruction(pc_real);
397399
}
398400
ppc_state.pc = eb_start;
399401
exec_flags = 0;
400402
} else {
401403
ppc_state.pc += 4;
402404
pc_real += 4;
403-
ppc_set_cur_instruction(pc_real);
405+
opcode = ppc_read_instruction(pc_real);
404406
}
405407
}
406408
}
@@ -431,8 +433,9 @@ void ppc_exec_single()
431433
return;
432434
}
433435

434-
mmu_translate_imem(ppc_state.pc);
435-
ppc_main_opcode();
436+
uint8_t* pc_real = mmu_translate_imem(ppc_state.pc);
437+
uint32_t opcode = ppc_read_instruction(pc_real);
438+
ppc_main_opcode(opcode);
436439
g_icycles++;
437440
process_events();
438441

@@ -452,6 +455,7 @@ static void ppc_exec_until_inner(const uint32_t goal_addr)
452455
uint64_t max_cycles;
453456
uint32_t page_start, eb_start, eb_end;
454457
uint8_t* pc_real;
458+
uint32_t opcode;
455459

456460
max_cycles = 0;
457461

@@ -464,10 +468,11 @@ static void ppc_exec_until_inner(const uint32_t goal_addr)
464468
exec_flags = 0;
465469

466470
pc_real = mmu_translate_imem(eb_start);
471+
opcode = ppc_read_instruction(pc_real);
467472

468473
// interpret execution block
469474
while (power_on && ppc_state.pc < eb_end) {
470-
ppc_main_opcode();
475+
ppc_main_opcode(opcode);
471476
if (g_icycles++ >= max_cycles || exec_timer) {
472477
max_cycles = process_events();
473478
}
@@ -477,18 +482,19 @@ static void ppc_exec_until_inner(const uint32_t goal_addr)
477482
eb_start = ppc_next_instruction_address;
478483
if (!(exec_flags & EXEF_RFI) && (eb_start & PPC_PAGE_MASK) == page_start) {
479484
pc_real += (int)eb_start - (int)ppc_state.pc;
480-
ppc_set_cur_instruction(pc_real);
485+
opcode = ppc_read_instruction(pc_real);
481486
} else {
482487
page_start = eb_start & PPC_PAGE_MASK;
483488
eb_end = page_start + PPC_PAGE_SIZE - 1;
484489
pc_real = mmu_translate_imem(eb_start);
490+
opcode = ppc_read_instruction(pc_real);
485491
}
486492
ppc_state.pc = eb_start;
487493
exec_flags = 0;
488494
} else {
489495
ppc_state.pc += 4;
490496
pc_real += 4;
491-
ppc_set_cur_instruction(pc_real);
497+
opcode = ppc_read_instruction(pc_real);
492498
}
493499

494500
if (ppc_state.pc == goal_addr)
@@ -519,6 +525,7 @@ static void ppc_exec_dbg_inner(const uint32_t start_addr, const uint32_t size)
519525
uint64_t max_cycles;
520526
uint32_t page_start, eb_start, eb_end;
521527
uint8_t* pc_real;
528+
uint32_t opcode;
522529

523530
max_cycles = 0;
524531

@@ -531,11 +538,12 @@ static void ppc_exec_dbg_inner(const uint32_t start_addr, const uint32_t size)
531538
exec_flags = 0;
532539

533540
pc_real = mmu_translate_imem(eb_start);
541+
opcode = ppc_read_instruction(pc_real);
534542

535543
// interpret execution block
536544
while (power_on && (ppc_state.pc < start_addr || ppc_state.pc >= start_addr + size)
537545
&& (ppc_state.pc < eb_end)) {
538-
ppc_main_opcode();
546+
ppc_main_opcode(opcode);
539547
if (g_icycles++ >= max_cycles || exec_timer) {
540548
max_cycles = process_events();
541549
}
@@ -545,18 +553,19 @@ static void ppc_exec_dbg_inner(const uint32_t start_addr, const uint32_t size)
545553
eb_start = ppc_next_instruction_address;
546554
if (!(exec_flags & EXEF_RFI) && (eb_start & PPC_PAGE_MASK) == page_start) {
547555
pc_real += (int)eb_start - (int)ppc_state.pc;
548-
ppc_set_cur_instruction(pc_real);
556+
opcode = ppc_read_instruction(pc_real);
549557
} else {
550558
page_start = eb_start & PPC_PAGE_MASK;
551559
eb_end = page_start + PPC_PAGE_SIZE - 1;
552560
pc_real = mmu_translate_imem(eb_start);
561+
opcode = ppc_read_instruction(pc_real);
553562
}
554563
ppc_state.pc = eb_start;
555564
exec_flags = 0;
556565
} else {
557566
ppc_state.pc += 4;
558567
pc_real += 4;
559-
ppc_set_cur_instruction(pc_real);
568+
opcode = ppc_read_instruction(pc_real);
560569
}
561570
}
562571
}

0 commit comments

Comments
 (0)