From fcd5cdd5aeecf7eae91a402755c260bb64a0fe0f Mon Sep 17 00:00:00 2001 From: Dimitar Dimitrov Date: Fri, 8 Dec 2023 20:39:10 +0200 Subject: sim: pru: Fix emulation of carry bit The PRU architecture documentation [1] was used for the initial GNU simulator implementation. But recently [2] TI confirmed the carry behaviour was wrongly documented. In reality, the PRU carry behaves like the carry in ARM processors. This patch fixes simulator to align with latest recommendations from TI. The new carry.s test was also validated to pass on real hardware - a BeaglePlay board [3]. That test is a bit long because TI still has not released official updates for the PRU documents. And I wanted to ensure simulator handles all edge cases exactly as the real hardware does. [1] https://www.ti.com/lit/pdf/spruij2 [2] https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1244359/sk-am64b-am64x-pru-assembler-how-works-this-bloody-carry [3] https://www.beagleboard.org/boards/beagleplay Signed-off-by: Dimitar Dimitrov --- sim/pru/pru.isa | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'sim/pru') diff --git a/sim/pru/pru.isa b/sim/pru/pru.isa index fb2d049..e88522b 100644 --- a/sim/pru/pru.isa +++ b/sim/pru/pru.isa @@ -40,26 +40,30 @@ INSTRUCTION (sub, OP2 = (IO ? IMM8 : RS2); RD = RS1 - OP2; CARRY = (((uint64_t) RS1 - (uint64_t) OP2) >> RD_WIDTH) & 1; + CARRY = !CARRY; PC++) INSTRUCTION (suc, OP2 = (IO ? IMM8 : RS2); - RD = RS1 - OP2 - CARRY; - CARRY = (((uint64_t) RS1 - (uint64_t) OP2 - (uint64_t) CARRY) + RD = RS1 - OP2 - !CARRY; + CARRY = (((uint64_t) RS1 - (uint64_t) OP2 - (uint64_t) !CARRY) >> RD_WIDTH) & 1; + CARRY = !CARRY; PC++) INSTRUCTION (rsb, OP2 = (IO ? IMM8 : RS2); RD = OP2 - RS1; CARRY = (((uint64_t) OP2 - (uint64_t) RS1) >> RD_WIDTH) & 1; + CARRY = !CARRY; PC++) INSTRUCTION (rsc, OP2 = (IO ? IMM8 : RS2); - RD = OP2 - RS1 - CARRY; - CARRY = (((uint64_t) OP2 - (uint64_t) RS1 - (uint64_t) CARRY) + RD = OP2 - RS1 - !CARRY; + CARRY = (((uint64_t) OP2 - (uint64_t) RS1 - (uint64_t) !CARRY) >> RD_WIDTH) & 1; + CARRY = !CARRY; PC++) INSTRUCTION (lsl, -- cgit v1.1