Inline m68k assembly: internal error 200405011 assembling the dc.b/dc.w/dc.l pseudo-instruction

Summary

When crosscompiling for Atari ST (Motorola 68000) using an inline asm ... end; block, the dc.b, dc.w, or dc.l pseudo-instruction doesn't assemble and causes an internal error 200405011.

See the forum post.

System Information

  • Operating system: Ubuntu 22.04.1 LTS
  • Processor architecture: x86_64
  • Compiler version: FPC 3.2.2 x86_64-linux-gtk2 shipped with Lazarus 2.2.4 stable as a deb package
  • Device: Computer

Steps to reproduce

  1. Set up the m68k/Atari crosscompilation environment
  2. Try to compile the test Lazarus project. With FPC only, the command line is:
    ppc68k -Tatari -Cp68000 dctest.lpr
    vasm & vlink variant:
    ppc68k -Tatari -Cp68000 -Avasm -XV dctest.lpr

Example Project

https://gitlab.com/pavel.reznicek/dc-test

What is the current bug behavior?

See summary.

Tried to compile the original source with vasm. It has no problems with the dc.* pseudo-instructions.

What is the expected (correct) behavior?

The dc.b/dc.w/dc.l pseudo-instructions should assemble.

Relevant logs and/or screenshots

Test project file:

program dctest;

{$mode objfpc}{$H+}

{$APPTYPE GUI}

begin
  asm
    dc.b 0                  // store two bytes
    dc.b $00
    dc.b $FF,$FF            // store other two bytes
    dc.w $0001              // store a word
    dc.l $FFFFFFFF          // store a longword
  end;
end;

Compilation log:

Compile Project, OS: atari, CPU: m68k, Target: dctest: Exit code 1, Errors: 1
Free Pascal Compiler version 3.2.2 [2022/09/25] for m68k
dctest.lpr(9,10) Error: Internal error 200405011

Possible fixes

FPDebug Backtrace:

#0 CONCATCONSTANT(TASMLIST($00007F6673EB4A80), 0, 255) at /usr/share/fpcsrc/3.2.2/compiler/rautils.pas:1738
#1 TM68KMOTREADER.BUILDCONSTANT(TM68KMOTREADER($00007F6673E5C380), 255) at /usr/share/fpcsrc/3.2.2/compiler/m68k/ra68kmot.pas:970
#2 TM68KMOTREADER.ASSEMBLE(TM68KMOTREADER($00007F6673E5C380)) at /usr/share/fpcsrc/3.2.2/compiler/m68k/ra68kmot.pas:1707
#3 _ASM_STATEMENT at /usr/share/fpcsrc/3.2.2/compiler/pstatmnt.pas:1054
#4 STATEMENT at /usr/share/fpcsrc/3.2.2/compiler/pstatmnt.pas:1216
#5 STATEMENT_BLOCK(_BEGIN) at /usr/share/fpcsrc/3.2.2/compiler/pstatmnt.pas:1360
#6 BLOCK(False) at /usr/share/fpcsrc/3.2.2/compiler/psub.pas:374
#7 TCGPROCINFO.PARSE_BODY(TCGPROCINFO($00007F667463B040)) at /usr/share/fpcsrc/3.2.2/compiler/psub.pas:1909
#8 PROC_PROGRAM(False) at /usr/share/fpcsrc/3.2.2/compiler/pmodules.pas:2166
#9 COMPILE('dctest.lpr') at /usr/share/fpcsrc/3.2.2/compiler/parser.pas:407
#10  at :0
#11  at :0
#12  at :0

Some notes to the situation

The constsize parameter is equal to 255 in this case but the ConcatConstant procedure evidently expects only byte, word, longword, and qword constants.

However, the dc.b pseudo-instruction can store many bytes (yes, 255 is a reasonable maximum) and can contain a kind of string expressions, dc.w can store many words, and dc.l many longwords, respectively.

dc.* examples:

dc.b 'Hello world!',$0 // a PChar body
dc.b 0,1,2,3,4         // Yes, an odd number of bytes! 
dc.w $0000,$FFFF       // Two words
dc.l $0000FFFF         // The same bytes as the above example
dc.l $0000FFFF,5       // Equal to dc.b 0,0,255,255,0,0,0,5
Edited by Pavel Řezníček