Skip to content

Commit 1533dae

Browse files
committed
perf(rp2040): optimize instruction fetch / RAM accesss
- Speed up instruction fetch by optimizing flash reads - Skip 32-bit opcode fetch for 16-bit instructions - Speed up narrow RAM access (8 and 16-bits)
1 parent 893b467 commit 1533dae

File tree

1 file changed

+25
-1
lines changed

1 file changed

+25
-1
lines changed

src/rp2040.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,11 +371,23 @@ export class RP2040 {
371371

372372
/** We assume the address is 16-bit aligned */
373373
readUint16(address: number) {
374+
if (address >= FLASH_START_ADDRESS && address < FLASH_END_ADDRESS) {
375+
return this.flashView.getUint16(address - FLASH_START_ADDRESS, true);
376+
} else if (address >= RAM_START_ADDRESS && address < RAM_START_ADDRESS + this.sram.length) {
377+
return this.sramView.getUint16(address - RAM_START_ADDRESS, true);
378+
}
379+
374380
const value = this.readUint32(address & 0xfffffffc);
375381
return address & 0x2 ? (value & 0xffff0000) >>> 16 : value & 0xffff;
376382
}
377383

378384
readUint8(address: number) {
385+
if (address >= FLASH_START_ADDRESS && address < FLASH_END_ADDRESS) {
386+
return this.flash[address - FLASH_START_ADDRESS];
387+
} else if (address >= RAM_START_ADDRESS && address < RAM_START_ADDRESS + this.sram.length) {
388+
return this.sram[address - RAM_START_ADDRESS];
389+
}
390+
379391
const value = this.readUint16(address & 0xfffffffe);
380392
return (address & 0x1 ? (value & 0xff00) >>> 8 : value & 0xff) >>> 0;
381393
}
@@ -411,6 +423,11 @@ export class RP2040 {
411423
}
412424

413425
writeUint8(address: number, value: number) {
426+
if (address >= RAM_START_ADDRESS && address < RAM_START_ADDRESS + this.sram.length) {
427+
this.sram[address - RAM_START_ADDRESS] = value;
428+
return;
429+
}
430+
414431
const alignedAddress = (address & 0xfffffffc) >>> 0;
415432
const offset = address & 0x3;
416433
const peripheral = this.findPeripheral(address);
@@ -433,6 +450,12 @@ export class RP2040 {
433450
writeUint16(address: number, value: number) {
434451
// we assume that addess is 16-bit aligned.
435452
// Ideally we should generate a fault if not!
453+
454+
if (address >= RAM_START_ADDRESS && address < RAM_START_ADDRESS + this.sram.length) {
455+
this.sramView.setUint16(address - RAM_START_ADDRESS, value, true);
456+
return;
457+
}
458+
436459
const alignedAddress = (address & 0xfffffffc) >>> 0;
437460
const offset = address & 0x3;
438461
const peripheral = this.findPeripheral(address);
@@ -791,7 +814,8 @@ export class RP2040 {
791814
// ARM Thumb instruction encoding - 16 bits / 2 bytes
792815
const opcodePC = this.PC & ~1; //ensure no LSB set PC are executed
793816
const opcode = this.readUint16(opcodePC);
794-
const opcode2 = this.readUint16(opcodePC + 2);
817+
const wideInstruction = opcode >> 12 === 0b1111 || opcode >> 13 === 0b11101;
818+
const opcode2 = wideInstruction ? this.readUint16(opcodePC + 2) : 0;
795819
this.PC += 2;
796820
this.cycles++;
797821
// ADCS

0 commit comments

Comments
 (0)