Skip to content

ARMv4 halfword/signed loads and stores are silently executed as data-processing instructions #4

Description

@ajfa

The ARM710T in the Series 5mx is ARMv4T, but ARM710::executeInstruction has no
case for the ARMv4 "extra load/store" group (LDRH / STRH / LDRSB / LDRSH). Those
instructions fall through to the catch-all

else if ((i & 0x0C000000) == 0x00000000)
    cycles += execDataProcessing(...);

and are executed as data-processing operations. There is no Undefined32
exception and no diagnostic: the instruction silently writes a garbage value to
Rd, may update the flags, and never touches memory.

Concrete example

EPOC R5's ATA media driver reads a sector through a 16-bit block-copy loop in
EpBus.dll at 0x500553d4:

500553f0  e1d020b0  ldrh r2, [r0]
500553f4  e1d030b0  ldrh r3, [r0]
500553f8  e1822803  orr  r2, r2, r3, lsl #16
500553fc  e4852004  str  r2, [r5], #4
50055400  e1550006  cmp  r5, r6
50055404  3afffff9  blo  #0x500553f0

0xe1d020b0 & 0x0C000000 == 0, so it is dispatched to execDataProcessing,
which decodes bits 24:21 = 0xE as BIC with S=1 and Rd=2. The emulator therefore
computes BICS r2, r0, ... instead of loading a halfword: no bus access is
generated at all, and the condition flags are clobbered as a side effect.

Observable symptom: EPOC issues an ATA IDENTIFY DEVICE, the device asserts DRQ,
and EPOC then requests the data block — but the emulated hardware sees zero reads
of the data register, because the loop never performs a memory access.

Second, related issue

Implementing the group needs a 16-bit access size, which the memory bus does not
have:

enum ValueSize { V8 = 0, V32 = 1 };

Splitting a halfword into two V8 accesses is not equivalent for 16-bit
peripherals. On a PC card ATA task file, offset 0 is the 16-bit Data register
while offset 1 is the Error/Feature register, so two byte reads return one data
byte and one unrelated register value. A V16 that reaches readPhysical /
writePhysical is needed; for plain RAM and ROM it can be composed from two byte
accesses.

Scope

Any EPOC code path using halfword or signed loads is affected, not just PC card
access. Because the failure is silent, it presents as unrelated misbehaviour
elsewhere.

Tested against s5mx_uk16_v260.rom (Series 5mx v1.05(260), CRC32 3b25a6a4).


Investigation and testing by @ajfa, with Claude (Anthropic) assisting.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions