From f8cca9e43cd7c395e3a581e89be087a79cae8514 Mon Sep 17 00:00:00 2001 From: Turro75 Date: Sun, 16 May 2021 16:06:54 +0200 Subject: [PATCH 1/9] fix(rp2040): SBCS xPSR Flags Handling --- src/instructions.spec.ts | 26 ++++++++++++++++++++++++++ src/rp2040.ts | 6 +++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/instructions.spec.ts b/src/instructions.spec.ts index 4db2e22..d1112f2 100644 --- a/src/instructions.spec.ts +++ b/src/instructions.spec.ts @@ -1055,6 +1055,32 @@ describe('Cortex-M0+ Instruction Set', () => { expect(registers.V).toEqual(false); }); + it('should execute a `sbcs r0, r3` instruction', async () => { + await cpu.setPC(0x20000000); + await cpu.writeUint16(0x20000000, opcodeSBCS(r0, r3)); + await cpu.setRegisters({ r0: 0, r3: 0xffffffff, C: false }); + await cpu.singleStep(); + const registers = await cpu.readRegisters(); + expect(registers.r0).toEqual(0); + expect(registers.N).toEqual(false); + expect(registers.Z).toEqual(true); + expect(registers.C).toEqual(false); + expect(registers.V).toEqual(false); + }); + + it('should execute a `sbcs r5, r7` instruction', async () => { + await cpu.setPC(0x20000000); + await cpu.writeUint16(0x20000000, opcodeSBCS(r5, r7)); + await cpu.setRegisters({ r5: 0, r7: 0, C: true }); + await cpu.singleStep(); + const registers = await cpu.readRegisters(); + expect(registers.r0).toEqual(0); + expect(registers.N).toEqual(false); + expect(registers.Z).toEqual(true); + expect(registers.C).toEqual(true); + expect(registers.V).toEqual(false); + }); + it('should execute a `sdmia r0!, {r1, r2}` instruction', async () => { await cpu.setPC(0x20000000); await cpu.writeUint16(0x20000000, opcodeSTMIA(r0, (1 << r1) | (1 << r2))); diff --git a/src/rp2040.ts b/src/rp2040.ts index d63af4a..3db6262 100644 --- a/src/rp2040.ts +++ b/src/rp2040.ts @@ -1410,7 +1410,7 @@ export class RP2040 { else if (opcode === 0b1011111100000000) { // Do nothing! } - // SBCS (Encoding T2) + // SBCS (Encoding T1) else if (opcode >> 6 === 0b0100000110) { const Rm = (opcode >> 3) & 0x7; const Rdn = opcode & 0x7; @@ -1418,8 +1418,8 @@ export class RP2040 { const operand2 = this.registers[Rm] + (this.C ? 0 : 1); const result = (operand1 - operand2) | 0; this.registers[Rdn] = result; - this.N = operand1 < operand2; - this.Z = operand1 === operand2; + this.N = (operand1 | 0) < (operand2 | 0); + this.Z = (operand1 | 0) === (operand2 | 0); this.C = operand1 >= operand2; this.V = (operand1 | 0) < 0 && operand2 > 0 && result > 0; } From 86b496a87df6b67b3e14e5a53879353c5701a8cd Mon Sep 17 00:00:00 2001 From: Turro75 Date: Sun, 16 May 2021 16:13:55 +0200 Subject: [PATCH 2/9] Revert "fix(rp2040): SBCS xPSR Flags Handling" This reverts commit f8cca9e43cd7c395e3a581e89be087a79cae8514. --- src/instructions.spec.ts | 26 -------------------------- src/rp2040.ts | 6 +++--- 2 files changed, 3 insertions(+), 29 deletions(-) diff --git a/src/instructions.spec.ts b/src/instructions.spec.ts index d1112f2..4db2e22 100644 --- a/src/instructions.spec.ts +++ b/src/instructions.spec.ts @@ -1055,32 +1055,6 @@ describe('Cortex-M0+ Instruction Set', () => { expect(registers.V).toEqual(false); }); - it('should execute a `sbcs r0, r3` instruction', async () => { - await cpu.setPC(0x20000000); - await cpu.writeUint16(0x20000000, opcodeSBCS(r0, r3)); - await cpu.setRegisters({ r0: 0, r3: 0xffffffff, C: false }); - await cpu.singleStep(); - const registers = await cpu.readRegisters(); - expect(registers.r0).toEqual(0); - expect(registers.N).toEqual(false); - expect(registers.Z).toEqual(true); - expect(registers.C).toEqual(false); - expect(registers.V).toEqual(false); - }); - - it('should execute a `sbcs r5, r7` instruction', async () => { - await cpu.setPC(0x20000000); - await cpu.writeUint16(0x20000000, opcodeSBCS(r5, r7)); - await cpu.setRegisters({ r5: 0, r7: 0, C: true }); - await cpu.singleStep(); - const registers = await cpu.readRegisters(); - expect(registers.r0).toEqual(0); - expect(registers.N).toEqual(false); - expect(registers.Z).toEqual(true); - expect(registers.C).toEqual(true); - expect(registers.V).toEqual(false); - }); - it('should execute a `sdmia r0!, {r1, r2}` instruction', async () => { await cpu.setPC(0x20000000); await cpu.writeUint16(0x20000000, opcodeSTMIA(r0, (1 << r1) | (1 << r2))); diff --git a/src/rp2040.ts b/src/rp2040.ts index 3db6262..d63af4a 100644 --- a/src/rp2040.ts +++ b/src/rp2040.ts @@ -1410,7 +1410,7 @@ export class RP2040 { else if (opcode === 0b1011111100000000) { // Do nothing! } - // SBCS (Encoding T1) + // SBCS (Encoding T2) else if (opcode >> 6 === 0b0100000110) { const Rm = (opcode >> 3) & 0x7; const Rdn = opcode & 0x7; @@ -1418,8 +1418,8 @@ export class RP2040 { const operand2 = this.registers[Rm] + (this.C ? 0 : 1); const result = (operand1 - operand2) | 0; this.registers[Rdn] = result; - this.N = (operand1 | 0) < (operand2 | 0); - this.Z = (operand1 | 0) === (operand2 | 0); + this.N = operand1 < operand2; + this.Z = operand1 === operand2; this.C = operand1 >= operand2; this.V = (operand1 | 0) < 0 && operand2 > 0 && result > 0; } From 867a464799ca1da48800f51ac6245807e944002f Mon Sep 17 00:00:00 2001 From: Turro75 Date: Sun, 16 May 2021 16:20:11 +0200 Subject: [PATCH 3/9] fix(rp2040): Fix SBCS flags handling Close #29 --- src/instructions.spec.ts | 13 +++++++++++++ src/rp2040.ts | 6 +++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/instructions.spec.ts b/src/instructions.spec.ts index 4db2e22..d723d67 100644 --- a/src/instructions.spec.ts +++ b/src/instructions.spec.ts @@ -1055,6 +1055,19 @@ describe('Cortex-M0+ Instruction Set', () => { expect(registers.V).toEqual(false); }); + it('should execute a `sbcs r0, r3` instruction', async () => { + await cpu.setPC(0x20000000); + await cpu.writeUint16(0x20000000, opcodeSBCS(r0, r3)); + await cpu.setRegisters({ r0: 0, r3: 0xffffffff, C: false }); + await cpu.singleStep(); + const registers = await cpu.readRegisters(); + expect(registers.r0).toEqual(0); + expect(registers.N).toEqual(false); + expect(registers.Z).toEqual(true); + expect(registers.C).toEqual(false); + expect(registers.V).toEqual(false); + }); + it('should execute a `sdmia r0!, {r1, r2}` instruction', async () => { await cpu.setPC(0x20000000); await cpu.writeUint16(0x20000000, opcodeSTMIA(r0, (1 << r1) | (1 << r2))); diff --git a/src/rp2040.ts b/src/rp2040.ts index d63af4a..3db6262 100644 --- a/src/rp2040.ts +++ b/src/rp2040.ts @@ -1410,7 +1410,7 @@ export class RP2040 { else if (opcode === 0b1011111100000000) { // Do nothing! } - // SBCS (Encoding T2) + // SBCS (Encoding T1) else if (opcode >> 6 === 0b0100000110) { const Rm = (opcode >> 3) & 0x7; const Rdn = opcode & 0x7; @@ -1418,8 +1418,8 @@ export class RP2040 { const operand2 = this.registers[Rm] + (this.C ? 0 : 1); const result = (operand1 - operand2) | 0; this.registers[Rdn] = result; - this.N = operand1 < operand2; - this.Z = operand1 === operand2; + this.N = (operand1 | 0) < (operand2 | 0); + this.Z = (operand1 | 0) === (operand2 | 0); this.C = operand1 >= operand2; this.V = (operand1 | 0) < 0 && operand2 > 0 && result > 0; } From f67732146c47e85ff29d408471a48bf6bdfe1b52 Mon Sep 17 00:00:00 2001 From: Turro75 Date: Sun, 16 May 2021 16:31:14 +0200 Subject: [PATCH 4/9] Revert "fix(rp2040): Fix SBCS flags handling" This reverts commit 867a464799ca1da48800f51ac6245807e944002f. --- src/instructions.spec.ts | 13 ------------- src/rp2040.ts | 6 +++--- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/src/instructions.spec.ts b/src/instructions.spec.ts index d723d67..4db2e22 100644 --- a/src/instructions.spec.ts +++ b/src/instructions.spec.ts @@ -1055,19 +1055,6 @@ describe('Cortex-M0+ Instruction Set', () => { expect(registers.V).toEqual(false); }); - it('should execute a `sbcs r0, r3` instruction', async () => { - await cpu.setPC(0x20000000); - await cpu.writeUint16(0x20000000, opcodeSBCS(r0, r3)); - await cpu.setRegisters({ r0: 0, r3: 0xffffffff, C: false }); - await cpu.singleStep(); - const registers = await cpu.readRegisters(); - expect(registers.r0).toEqual(0); - expect(registers.N).toEqual(false); - expect(registers.Z).toEqual(true); - expect(registers.C).toEqual(false); - expect(registers.V).toEqual(false); - }); - it('should execute a `sdmia r0!, {r1, r2}` instruction', async () => { await cpu.setPC(0x20000000); await cpu.writeUint16(0x20000000, opcodeSTMIA(r0, (1 << r1) | (1 << r2))); diff --git a/src/rp2040.ts b/src/rp2040.ts index 3db6262..d63af4a 100644 --- a/src/rp2040.ts +++ b/src/rp2040.ts @@ -1410,7 +1410,7 @@ export class RP2040 { else if (opcode === 0b1011111100000000) { // Do nothing! } - // SBCS (Encoding T1) + // SBCS (Encoding T2) else if (opcode >> 6 === 0b0100000110) { const Rm = (opcode >> 3) & 0x7; const Rdn = opcode & 0x7; @@ -1418,8 +1418,8 @@ export class RP2040 { const operand2 = this.registers[Rm] + (this.C ? 0 : 1); const result = (operand1 - operand2) | 0; this.registers[Rdn] = result; - this.N = (operand1 | 0) < (operand2 | 0); - this.Z = (operand1 | 0) === (operand2 | 0); + this.N = operand1 < operand2; + this.Z = operand1 === operand2; this.C = operand1 >= operand2; this.V = (operand1 | 0) < 0 && operand2 > 0 && result > 0; } From 5c39f368e74bbb78e2c1bbf3023dc694c651e631 Mon Sep 17 00:00:00 2001 From: Turro75 Date: Sun, 16 May 2021 16:34:39 +0200 Subject: [PATCH 5/9] fix(rp2040): Fix SBCS flags handling Close #29 --- src/instructions.spec.ts | 13 +++++++++++++ src/rp2040.ts | 6 +++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/instructions.spec.ts b/src/instructions.spec.ts index 4db2e22..d723d67 100644 --- a/src/instructions.spec.ts +++ b/src/instructions.spec.ts @@ -1055,6 +1055,19 @@ describe('Cortex-M0+ Instruction Set', () => { expect(registers.V).toEqual(false); }); + it('should execute a `sbcs r0, r3` instruction', async () => { + await cpu.setPC(0x20000000); + await cpu.writeUint16(0x20000000, opcodeSBCS(r0, r3)); + await cpu.setRegisters({ r0: 0, r3: 0xffffffff, C: false }); + await cpu.singleStep(); + const registers = await cpu.readRegisters(); + expect(registers.r0).toEqual(0); + expect(registers.N).toEqual(false); + expect(registers.Z).toEqual(true); + expect(registers.C).toEqual(false); + expect(registers.V).toEqual(false); + }); + it('should execute a `sdmia r0!, {r1, r2}` instruction', async () => { await cpu.setPC(0x20000000); await cpu.writeUint16(0x20000000, opcodeSTMIA(r0, (1 << r1) | (1 << r2))); diff --git a/src/rp2040.ts b/src/rp2040.ts index d63af4a..3db6262 100644 --- a/src/rp2040.ts +++ b/src/rp2040.ts @@ -1410,7 +1410,7 @@ export class RP2040 { else if (opcode === 0b1011111100000000) { // Do nothing! } - // SBCS (Encoding T2) + // SBCS (Encoding T1) else if (opcode >> 6 === 0b0100000110) { const Rm = (opcode >> 3) & 0x7; const Rdn = opcode & 0x7; @@ -1418,8 +1418,8 @@ export class RP2040 { const operand2 = this.registers[Rm] + (this.C ? 0 : 1); const result = (operand1 - operand2) | 0; this.registers[Rdn] = result; - this.N = operand1 < operand2; - this.Z = operand1 === operand2; + this.N = (operand1 | 0) < (operand2 | 0); + this.Z = (operand1 | 0) === (operand2 | 0); this.C = operand1 >= operand2; this.V = (operand1 | 0) < 0 && operand2 > 0 && result > 0; } From 0cdd227bb48a42295488047a61e610ddbf7ea34f Mon Sep 17 00:00:00 2001 From: Turro75 Date: Sun, 16 May 2021 21:23:28 +0200 Subject: [PATCH 6/9] fix(rp2040): CMP reg T1 Carry handling --- src/instructions.spec.ts | 13 +++++++++++++ src/rp2040.ts | 8 ++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/instructions.spec.ts b/src/instructions.spec.ts index d723d67..0fca339 100644 --- a/src/instructions.spec.ts +++ b/src/instructions.spec.ts @@ -469,6 +469,19 @@ describe('Cortex-M0+ Instruction Set', () => { expect(registers.V).toEqual(false); }); + it('should execute an `cmp r2, r0` instruction', async () => { + await cpu.setPC(0x20000000); + await cpu.writeUint16(0x20000000, opcodeCMPregT1(r2, r0)); + await cpu.setRegisters({ r0: 0xb71b0000 }); + await cpu.setRegisters({ r2: 0x00b71b00 }); + await cpu.setRegisters({ xPSR: 0x61000000 }); + await cpu.singleStep(); + const registers = await cpu.readRegisters(); + expect(registers.N).toEqual(false); + expect(registers.Z).toEqual(false); + expect(registers.C).toEqual(false); + expect(registers.V).toEqual(false); + }); it('should correctly set carry flag when executing `cmp r11, r3` instruction', async () => { await cpu.setPC(0x20000000); await cpu.writeUint16(0x20000000, opcodeCMPregT2(r11, r3)); diff --git a/src/rp2040.ts b/src/rp2040.ts index 3db6262..da6a896 100644 --- a/src/rp2040.ts +++ b/src/rp2040.ts @@ -1028,10 +1028,10 @@ export class RP2040 { else if (opcode >> 6 === 0b0100001010) { const Rm = (opcode >> 3) & 0x7; const Rn = opcode & 0x7; - const leftValue = this.registers[Rn] | 0; - const rightValue = this.registers[Rm] | 0; - const result = (leftValue - rightValue) | 0; - this.N = leftValue < rightValue; + const leftValue = this.registers[Rn]; + const rightValue = this.registers[Rm]; + const result = ((leftValue | 0) - (rightValue | 0)) | 0; + this.N = result < 0; this.Z = leftValue === rightValue; this.C = leftValue >= rightValue; this.V = From fece8114e2e344978d781900282dc20f896b917b Mon Sep 17 00:00:00 2001 From: Turro75 Date: Sun, 16 May 2021 21:43:40 +0200 Subject: [PATCH 7/9] refactor as requested --- src/instructions.spec.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/instructions.spec.ts b/src/instructions.spec.ts index 0fca339..581a5d0 100644 --- a/src/instructions.spec.ts +++ b/src/instructions.spec.ts @@ -469,12 +469,10 @@ describe('Cortex-M0+ Instruction Set', () => { expect(registers.V).toEqual(false); }); - it('should execute an `cmp r2, r0` instruction', async () => { + it('should correctly unset carry when executing an `cmp r2, r0` instruction', async () => { await cpu.setPC(0x20000000); await cpu.writeUint16(0x20000000, opcodeCMPregT1(r2, r0)); - await cpu.setRegisters({ r0: 0xb71b0000 }); - await cpu.setRegisters({ r2: 0x00b71b00 }); - await cpu.setRegisters({ xPSR: 0x61000000 }); + await cpu.setRegisters({ r0: 0xb71b0000, r2: 0x00b71b00 }); await cpu.singleStep(); const registers = await cpu.readRegisters(); expect(registers.N).toEqual(false); @@ -482,6 +480,7 @@ describe('Cortex-M0+ Instruction Set', () => { expect(registers.C).toEqual(false); expect(registers.V).toEqual(false); }); + it('should correctly set carry flag when executing `cmp r11, r3` instruction', async () => { await cpu.setPC(0x20000000); await cpu.writeUint16(0x20000000, opcodeCMPregT2(r11, r3)); From 8fab43aff9ea005141cc8bebb88918118283fd57 Mon Sep 17 00:00:00 2001 From: Turro75 Date: Sun, 16 May 2021 21:50:00 +0200 Subject: [PATCH 8/9] set more specific name to added cmp test --- src/instructions.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/instructions.spec.ts b/src/instructions.spec.ts index 581a5d0..d1678b1 100644 --- a/src/instructions.spec.ts +++ b/src/instructions.spec.ts @@ -469,7 +469,7 @@ describe('Cortex-M0+ Instruction Set', () => { expect(registers.V).toEqual(false); }); - it('should correctly unset carry when executing an `cmp r2, r0` instruction', async () => { + it('should execute an cmp r2, r0 instruction and not set any flags when r0=0xb71b0000 and r2=0x00b71b00', async () => { await cpu.setPC(0x20000000); await cpu.writeUint16(0x20000000, opcodeCMPregT1(r2, r0)); await cpu.setRegisters({ r0: 0xb71b0000, r2: 0x00b71b00 }); From bc8435878920f381966f74844445738e11478578 Mon Sep 17 00:00:00 2001 From: Turro75 Date: Sun, 16 May 2021 22:01:54 +0200 Subject: [PATCH 9/9] equalize test name like other --- src/instructions.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/instructions.spec.ts b/src/instructions.spec.ts index d1678b1..80b1193 100644 --- a/src/instructions.spec.ts +++ b/src/instructions.spec.ts @@ -469,7 +469,7 @@ describe('Cortex-M0+ Instruction Set', () => { expect(registers.V).toEqual(false); }); - it('should execute an cmp r2, r0 instruction and not set any flags when r0=0xb71b0000 and r2=0x00b71b00', async () => { + it('should execute an `cmp r2, r0` instruction and not set any flags when r0=0xb71b0000 and r2=0x00b71b00', async () => { await cpu.setPC(0x20000000); await cpu.writeUint16(0x20000000, opcodeCMPregT1(r2, r0)); await cpu.setRegisters({ r0: 0xb71b0000, r2: 0x00b71b00 });