Skip to content

Commit

Permalink
fix(rp2040): SUBS alignment to CMP implementation
Browse files Browse the repository at this point in the history
close #56
  • Loading branch information
Turro75 authored and urish committed May 31, 2021
1 parent 33e6467 commit 50a3496
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 3 deletions.
28 changes: 28 additions & 0 deletions src/instructions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1325,6 +1325,34 @@ describe('Cortex-M0+ Instruction Set', () => {
expect(registers.V).toEqual(false);
});

it('should execute a `subs r5, r3, r2` instruction and set N V flags', async () => {
await cpu.setPC(0x20000000);
await cpu.writeUint16(0x20000000, opcodeSUBSreg(r5, r3, r2));
await cpu.setRegisters({ r3: 0 });
await cpu.setRegisters({ r2: 0x80000000 });
await cpu.singleStep();
const registers = await cpu.readRegisters();
expect(registers.r5).toEqual(0x80000000);
expect(registers.N).toEqual(true);
expect(registers.Z).toEqual(false);
expect(registers.C).toEqual(false);
expect(registers.V).toEqual(true);
});

it('should execute a `subs r5, r3, r2` instruction and set Z C flags', async () => {
await cpu.setPC(0x20000000);
await cpu.writeUint16(0x20000000, opcodeSUBSreg(r5, r3, r2));
await cpu.setRegisters({ r2: 0x80000000 });
await cpu.setRegisters({ r3: 0x80000000 });
await cpu.singleStep();
const registers = await cpu.readRegisters();
expect(registers.r5).toEqual(0);
expect(registers.N).toEqual(false);
expect(registers.Z).toEqual(true);
expect(registers.C).toEqual(true);
expect(registers.V).toEqual(false);
});

it('should raise an SVCALL exception when `svc` instruction runs', async () => {
const SVCALL_HANDLER = 0x20002000;
await cpu.setRegisters({ sp: 0x20004000 });
Expand Down
8 changes: 5 additions & 3 deletions src/rp2040.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1633,12 +1633,14 @@ export class RP2040 {
const Rd = opcode & 0x7;
const leftValue = this.registers[Rn];
const rightValue = this.registers[Rm];
const result = (leftValue - rightValue) | 0;
const result = leftValue - rightValue;
this.registers[Rd] = result;
this.N = (leftValue | 0) < (rightValue | 0);
this.N = !!(result & 0x80000000);
this.Z = leftValue === rightValue;
this.C = leftValue >= rightValue;
this.V = (leftValue | 0) < 0 && rightValue > 0 && result > 0;
this.V =
(!!(result & 0x80000000) && !(leftValue & 0x80000000) && !!(rightValue & 0x80000000)) ||
(!(result & 0x80000000) && !!(leftValue & 0x80000000) && !(rightValue & 0x80000000));
}
// SVC
else if (opcode >> 8 === 0b11011111) {
Expand Down

0 comments on commit 50a3496

Please sign in to comment.