Skip to content

M68K: Fix fmove.x 96-bit extended immediate decode length and printing - #3016

Merged
Rot127 merged 3 commits into
capstone-engine:nextfrom
b1llow:m68k-fix-96b
Aug 30, 2026
Merged

M68K: Fix fmove.x 96-bit extended immediate decode length and printing#3016
Rot127 merged 3 commits into
capstone-engine:nextfrom
b1llow:m68k-fix-96b

Conversation

@b1llow

@b1llow b1llow commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Your checklist for this pull request

  • I've documented or updated the documentation of every API function and struct this PR changes.
  • I've added tests that prove my fix is effective or that my feature works (if possible)

Detailed description

Summary

M68K fmove.x and fmove.p inline immediates use 12-byte Motorola external operands. The decoder now consumes all 12 operand bytes, preserves the complete representation in dedicated lossless detail types, and prints useful assembly text. Packed register-to-memory moves also expose and print their static or dynamic k-factor.

References

Motorola MC68881/MC68882 Floating-Point Coprocessor User's Manual, first edition (1987):

https://www.bitsavers.org/components/motorola/68000/68020/MC68881_MC68882_Floating-Point_Coprocessor_Users_Manual_1ed_1987.pdf

Topic Manual
External Extended Precision Real (X) format Section 3, Table 3-3: a 96-bit/12-byte representation containing a 16-bit sign plus biased exponent, a 16-bit unused/reserved word, and a 64-bit significand with an explicit integer bit.
External Packed Decimal Real (P) format Sections 3.3 and 3.6, Table 3-4 and Figure 3-11: a 96-bit/12-byte packed-BCD string with separate mantissa and exponent signs, a three-digit exponent, and a 17-digit mantissa.
Immediate .x / .p operand size Section 4.7.1: both external formats occupy 12 bytes (six 16-bit words) after the F-line and command words.
Packed destination k-factor FMOVE description, pages 4-64 through 4-67, and Section 4.7.1.4/Table 4-16: packed register-to-memory conversion uses a signed 7-bit static k-factor or a data-register-supplied dynamic k-factor.

External representations

An extended immediate is retained as:

  • sign_exp: mantissa sign in bit 15 and the 15-bit biased exponent in bits 14-0
  • reserved: the external format's complete reserved word
  • significand: the explicit integer bit followed by 63 fraction bits

A packed-decimal immediate is retained as a high 32-bit header and low 64-bit fraction. Together they preserve the manual's complete layout:

Bits Field
95 SM, mantissa sign
94 SE, exponent sign
93:92 y, used with SE for infinity and NaN encodings
91:80 EXP2:EXP0, the three packed-BCD exponent digits
79:76 EXP3, generated on an overflowing move out; only EXP2:EXP0 are used on input
75:68 ignored/don't-care bits
67:64 MANT16, the integer mantissa digit
63:0 MANT15:MANT0, the sixteen packed-BCD fractional digits

For packed register-to-memory moves, the manual defines the k-factor as follows:

  • A static k-factor is the signed two's-complement value in the seven-bit extension field.
  • -64 through 0 select the number of significant digits to the right of the decimal point (Fortran F format).
  • +1 through +17 select the number of significant mantissa digits (Fortran E format).
  • +18 through +63 set OPERR and are treated as +17 by the coprocessor.
  • A dynamic encoding rrr0000 selects D0 through D7; the register's low seven bits contain the signed k-factor and its upper 25 bits are ignored.

Changes

  • Read the complete 12-byte external operand for inline fmove.x and fmove.p sources, rejecting truncated encodings instead of consuming sentinel data.
  • Add M68K_OP_FP_EXTENDED with fp_extended and M68K_OP_FP_PACKED with fp_packed, so detail consumers receive the complete external representation without rounding or discarding reserved bits.
  • Add M68K_FPU_SIZE_PACKED to distinguish .p from .x, even though both external operands are 12 bytes.
  • Print .x immediates in GNU-compatible #0e... form. extended_to_double() supplies a binary64 approximation only for this assembly-text %g path; the detail operand remains exact and is never stored in dimm.
  • Print .p immediates directly from their packed-BCD digits, including signed zero, infinity, NaN, and deterministic invalid-BCD text, without a floating-point approximation.
  • Keep memory .x and .p sources as M68K_OP_MEM; only inline #... values use the new value operand types.
  • Decode packed register-to-memory moves with a third detail operand for the static immediate or dynamic data-register k-factor, print {#k} / {dn}, and include the dynamic register in register-access details.
  • Export the new operand types, structures, fields, and size tag through the Python binding, and add matching Java and OCaml constants.
  • Extend the C and Python detail-test adapters and M68K detail fixtures for exact representations, 12-byte consumption and truncation, rounding boundaries used by .x text, special values, packed BCD, memory operands, and both k-factor forms.
  • Document the new M68K detail API in the v6 release guide and expose the exact fields in cstool -d output.

Result

For both immediate formats, the instruction is 16 bytes total: the F-line word, command word, and complete 12-byte external operand. Subsequent instructions therefore begin at the correct offset. Detail clients receive lossless .x / .p data, while disassembly remains human-readable.

Closing issues

closes #3013

@github-actions github-actions Bot added the M68K Arch label Aug 6, 2026
@Rot127

Rot127 commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Please add a PR description. What does the signing have to do with the bug?

Comment thread arch/M68K/M68KDisassembler.c Outdated
@github-actions github-actions Bot added Python Bindings java bindings ocaml bindings labels Aug 12, 2026

@Rot127 Rot127 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a note in the v6 guide please.

Comment thread tests/details/m68k.yaml
Comment thread cstool/cstool_m68k.c
Comment thread arch/M68K/M68KInstPrinter.c
Comment thread docs/cs_v6_release_guide.md Outdated
Comment thread docs/cs_v6_release_guide.md Outdated
@Rot127
Rot127 merged commit 95c74d3 into capstone-engine:next Aug 30, 2026
58 checks passed
@b1llow
b1llow deleted the m68k-fix-96b branch August 30, 2026 15:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Documentation java bindings M68K Arch ocaml bindings Python Bindings

Projects

None yet

Development

Successfully merging this pull request may close these issues.

M68K: Incorrect disassembly for fmove.x/fmove.p

2 participants