Skip to content

Implement LDR Instruction#22

Merged
lmSeryi merged 5 commits into
masterfrom
feat/ldr
Feb 3, 2026
Merged

Implement LDR Instruction#22
lmSeryi merged 5 commits into
masterfrom
feat/ldr

Conversation

@begeistert

Copy link
Copy Markdown
Collaborator

Description

  • Implement multiple Thumb LDR variants (immediate, literal, register, SP-relative) in CPU execution
  • Add ReadWordWithCycles helper to centralize memory reads and account for region-dependent cycle costs
  • Update memory operations to use the cycle-aware read helper for correct timing
  • Add LDR opcode handlers to the instruction decoder table so loads are recognized and dispatched
  • Add encoders in InstructionEmiter for LDR immediate, literal, register, and SP-relative forms with validation
  • Add unit tests for LDMIA and LDR variants and decoder tests to cover decoding/emission and cycle behavior

Type of change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 🧹 Refactoring (no functional changes, just code cleanup)

Checklist

  • 🧪 Tests passed locally (dotnet test)
  • ✅ Added new tests for this feature/fix
  • 📝 Documentation updated (if applicable)
  • 🚫 No "Magic Strings" or hardcoded values
  • 💾 Validated against the RP2040 Datasheet (if applicable)

Screenshots / Hex Dumps (Optional)

Implement multiple LDR addressing modes used by Thumb instructions:
- LdrImmediate: load word from [Rn + imm5<<2].
- LdrLiteral: load word from literal pool using aligned PC + imm8<<2.
- LdrRegister: load word from [Rn + Rm].
- LdrSpRelative: load word from [SP + imm8<<2].

Introduce ReadWordWithCycles helper to centralize memory reads and
account for region-dependent cycle costs (SRAM, APB/AHB, SIO, fallback).
Update existing memory ops to use the helper so cycle accounting is
consistent and correct.

These changes add missing instruction handlers and improve timing
accuracy when reading words from different bus regions.
Add missing LDR opcode rules to the instruction decoder so the CPU
can recognize and dispatch load instructions from various encodings:

- Add LDR (register) handler mapped to mask 0xFE00 / value 0x5800.
- Add LDR (literal) handler mapped to mask 0xF800 / value 0x4800.
- Add LDR (imm5) handler mapped to mask 0xF800 / value 0x6800.
- Add LDR (SP, imm8) handler mapped to mask 0xF800 / value 0x9800.

These entries complete support for common Thumb LDR encodings and are
needed so MemoryOps methods are invoked for load instructions instead
of falling through or causing incorrect decoding.
Add methods to InstructionEmiter to emit Thumb LDR variants:
- LdrImmediate(rt, rn, imm): LDR (register+imm) using imm>>2 as imm5.
- LdrLiteral(rt, imm): PC-relative LDR literal using imm>>2 as imm8.
- LdrRegister(rt, rn, rm): LDR register (register offset).
- LdrSpRelative(rt, imm): SP-relative LDR using imm>>2 as imm8.

Validate low register indexes and throw ArgumentException when out
of range. Implement opcodes and field placements per Thumb encoding
so the emitter can generate common LDR forms for the RP2040 core.
Add comprehensive unit tests for multiple load (LDMIA) and load
(LDR) instruction variants to expand CPU instruction coverage.

- Add Ldmia tests:
  - Should_LoadMultiple_And_WriteBackBaseAddress: verifies multiple
    register loads and base register write-back behavior.
  - Should_LoadMultiple_WithoutWriteBack_When_BaseIsLoaded:
    verifies case where base register is also a destination and no
    write-back occurs.
  - Should_ConsumeCorrectCycles_ForMultipleLoad: checks cycle
    consumption for multiple load.

- Add Ldr tests covering Immediate, Literal and Register forms:
  - Immediate: test Rn+immediate load and extra cycle when reading
    from peripheral.
  - Literal: test PC-relative loads including max offset boundary.
  - Register: start of a Register-form test to verify Rn+Rm addressing.

These tests improve correctness checks for memory addressing, data
loads, write-back semantics, and cycle counting in the CPU core.
Add unit tests for LDR variants to InstructionDecoderTests to cover
load operations emitted by InstructionEmiter. The new cases include:
LdrImmediate, LdrLiteral, LdrRegister and LdrSpRelative. Each test
compares the emitted opcode against the corresponding MemoryOps
handler to ensure decoding matches expected semantics.

This increases coverage for memory load instructions and prevents
regressions in decoder handling of immediate, literal, register and
SP-relative load encodings.
@begeistert
begeistert requested a review from lmSeryi as a code owner February 3, 2026 04:18
@sonarqubecloud

sonarqubecloud Bot commented Feb 3, 2026

Copy link
Copy Markdown

@begeistert begeistert self-assigned this Feb 3, 2026
@begeistert begeistert added the enhancement New feature or request label Feb 3, 2026
@lmSeryi

lmSeryi commented Feb 3, 2026

Copy link
Copy Markdown
Collaborator

LGTM

@lmSeryi
lmSeryi merged commit fb94b07 into master Feb 3, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants