# Summary of 32-bit Relocation Support for M68k LLVM Backend

This document summarizes the changes implemented to support comprehensive 32-bit relocations (`R_68K_PC32`, `R_68K_GOT32`, `R_68K_PLT32`, etc.) in the M68k backend, enabling support for Medium and Large code models on M68020+ processors.

## 1. Foundational ELF ABI Alignment
Fixed a critical mismatch between LLVM's internal relocation definitions and the standard M68k ELF ABI.
*   **File:** `llvm/include/llvm/BinaryFormat/ELFRelocs/M68k.def`
*   **Changes:** Refactored the entire relocation table to match official standards (as defined in `elf.h`). This correctly numbered GOT, PLT, and TLS relocations, ensuring compatibility with system linkers like `ld.bfd`.

## 2. Instruction Set Architecture (ISA) Support
Implemented the M68020+ "Full Format" extension word (0x0170/0x01b0) which supports 32-bit base displacements for addressing modes 6 and 7.
*   **Formats:** Added `MxEncAddrMode_q32` (PC-relative) and `MxEncAddrMode_p32` (Address Register Indirect).
*   **Instructions:**
    *   Expanded arithmetic (`ADD`, `SUB`, `CMP`), logic (`AND`, `OR`, `XOR`), and move (`MOVE`, `MOVEM`) instructions to support `q32` and `p32` modes.
    *   Implemented `LEA32q32` and `LEA32p32` for 32-bit address calculations.
    *   Added 32-bit extending loads (`MOVZX`/`MOVSX`).
    *   Implemented `CALLq32` (using `JSR`) for 32-bit PLT-relative function calls.
*   **Atomics:** Updated `M68kInstrAtomics.td` to remove illegal PC-relative stores, forcing a fallback to a legal `lea` + register-indirect sequence.

## 3. Code Model & Subtarget Logic
Updated the backend to recognize and utilize 32-bit displacements when the Medium or Large code model is active.
*   **File:** `llvm/lib/Target/M68k/M68kSubtarget.cpp`
*   **Changes:**
    *   `classifyGlobalReference` and `classifyGlobalFunctionReference` now return 32-bit target flags (`MO_PC_RELATIVE_ADDRESS_32`, etc.) for non-Small code models on M68020+.
    *   Added explicit detection for Thread-Local Storage (TLS) symbols to ensure they use correct TLS relocations.
*   **File:** `llvm/lib/Target/M68k/MCTargetDesc/M68kBaseInfo.h`
    *   Added `MO_PC_RELATIVE_ADDRESS_32` flag.
    *   Updated `isPCRelGlobalReference` to include `MO_PLT`.

## 4. Selection DAG & Lowering
Refined how symbolic references are matched and lowered into machine instructions.
*   **File:** `llvm/lib/Target/M68k/M68kISelLowering.cpp`
    *   Updated `LowerCall` to wrap symbolic targets in `WrapperPC32` for Medium/Large models.
    *   Implemented a short-circuit for `_GLOBAL_OFFSET_TABLE_` to resolve directly to the global base register, avoiding redundant relocations.
*   **File:** `llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp`
    *   Updated `matchAddressRecursively` to handle `ISD::GLOBAL_OFFSET_TABLE` as a PC-relative operation.
    *   Implemented "Store Fallback": Explicitly reject PC-relative matching for store-like operations (`STORE`, `ATOMIC_STORE`, `CMP_SWAP`). This forces the use of `LEA32q32` to compute the address into a register, adhering to hardware constraints.

## 5. Encoding & Binary Generation
Ensured that 32-bit displacements are correctly encoded and mapped to ELF relocation entries.
*   **File:** `llvm/lib/Target/M68k/MCTargetDesc/M68kMCCodeEmitter.cpp`
    *   Adjusted PC-relative fixup calculation for 32-bit modes. Full Format displacements are relative to the extension word address (+2 bytes), unlike 16-bit displacements which are relative to the instruction word.
*   **File:** `llvm/lib/Target/M68k/MCTargetDesc/M68kELFObjectWriter.cpp`
    *   Correctly mapped LLVM specifiers to ABI relocations:
        *   `S_GOTPCREL` -> `R_68K_GOT32` (PC-relative).
        *   `S_GOT` / `S_GOTOFF` -> `R_68K_GOT32O` (Offset-based).
        *   `S_GOTTPOFF` -> `R_68K_TLS_IE32`.
*   **File:** `llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp`
    *   Switched to `DecoderTable96` to support instruction widths of up to 96 bits (Opcode + 32-bit Disp + 32-bit Imm).

## Conclusion
These changes provide a robust, ABI-compliant implementation of 32-bit relocations. By utilizing the M68020's Full Format addressing and correctly aligning with the ELF standard, the backend now supports linking large binaries (up to 2GB) and complex libraries like the Rust standard library with full PIC and TLS support.
