Skip to content

pc bit1 "undefined" state on GBA not properly emulated #2964

@JoaoBaptMG

Description

@JoaoBaptMG

After some discussion on the gbadev Discord server, it was found that pc has a "weird" behaviour when a bx instruction is executed to ARM state with a mis-aligned address (aka bit 1 set): while the CPU is able to "internally" align the address to fetch an instruction with correct alignment, on pc the bit1 keeps set, which can lead to miscalculations in any instruction that uses it as an operand (such as pc-relative loads and stores).

We can check the vaildity of this hypothesis with a very simple subroutine that gets the pc on such a state:

08001708 <getMisalignedPC>:
 8001708:	46c0      	nop			@ (mov r8, r8)
 800170a:	4778      	bx	pc      @ this will branch to pc = 0800170e
 800170c:	e1a0000f 	mov	r0, pc  @ this will set r0 = mis-aligned pc: 08001716
 8001710:	e12fff1e 	bx	lr

(the source file is like this)

    .section .rom, "ax", %progbits
    .align 2
    .thumb_func
    .global getMisalignedPC
    .type getMisalignedPC STT_FUNC
getMisalignedPC:
    nop             ; to ensure mis-alignment (with the .align 2 up there)
    bx      pc      ; this instruction will fetch a pc whose set bit is 1
    .arm
    mov     r0, pc  ; this pc should be misaligned as well
    bx      lr

(I tried to upload a GBA ROM here, but GitHub doesn't let me)

On the hardware (tested by @evanbowman), the returned PC is what is expected by the above hypothesis:
Photo of a GBA hardware running the test. PC: 0x8001716, PC is mis-aligned

On mGBA, however, the returned PC is aligned to the lowest word (08001714), contradicting the result on hardware.
Screenshot of mGBA running the test. PC: 0x8001714, PC is aligned

This aligns with what the ARM7TDMI Technical Reference says about bits 1 and 0 of pc on ARM state:
Excerpt of the ARM7TDMI Technical Reference: "in ARM state, bits 1 and 0 of r15 are undefined and must be ignored."

Whether or not instructions having pc as an operand will correctly use the "correct" (aligned) program counter value is not tested (though I doubt, since bl in Thumb sets bit 1 of lr).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions