I have recently been porting a piece of Motorola 68000 assembly from asm68k syntax to GCC's m68k-elf-gcc, but am running into issues regarding the usage of labels. Notably, several link-time calculations appear to be unavailable, and label offsets which fit into an instruction's size when the address is directly provided throw errors when using the label.w syntax.
Before I begin, I would like to note that I am on the newest available version of the toolchain for Arch.
Division, & and bit-shifts on labels
The first problem regards the usage of division and the and operator on labels. In the original asm68k code, one macro was defined as:
move.l #0x96009500|((((\src)/2)&0xFF00)<<8)|(((\src)/2)&0xFF),VIDEO_CTRL.l
in which src is a label defined elsewhere in the code. This is extremely helpful, as the label never moves, so this calculation does the setup required to use hardware DMA to copy the memory at the label to the video controller's memory. This works flawlessly in asm68k, given its syntax, but in m68k-elf-as, it throws:
mainprg.s:754: Error: invalid operands (.data and *ABS* sections) for `/'
This applies to any section, be it .data, .text, or .bss. These operators are definitely not 100% necessary, but to calculate this at runtime would simply be a waste of CPU power, especially on a 68000. I would like to know, is there any way to replicate the behavior seen in asm68k?
Word-size label access
The second problem regards using the label.w syntax, which appears not to work whatsoever. In any instance of this syntax, the linker throws the following error:
(.text+0x6918): relocation truncated to fit: R_68K_16 against `.text'+da00
Although I understand why the error exists, but given the context, it makes no sense. The relative address, as it should be using, fits well within the range provided - and indeed, works perfectly fine in asm68k. Furthermore, when I used IDA to locate the address of the label in the compiled program and simply did 0xFFE752.w in m68k-elf-gcc, for example, it worked without error! Unfortunately, since this label may move pre-compile-time, I cannot simply use its address (I include several binary files which may change significantly in size before it in memory). This happens with any word address above 0xFFFF. In cases of instructions such as lea, I have been able to replace it with label(%pc), but this does not work in all cases, such as with addq.w.
Any solutions to either issue would be much appreciated, thank you!
Minimal Reproducible Examples:
Problem 1:
.section .data
variable:
.space 2
.section .text
label:
move.l #(variable/2), %d0
move.l #(variable&0xFF), %d0
move.l #(variable<<8), %d0
Errors thrown for problem 1:
testprg.s:6: Error: invalid operands (.data and *ABS* sections) for `/'
testprg.s:7: Error: invalid operands (.data and *ABS* sections) for `&'
testprg.s:8: Error: invalid operands (.data and *ABS* sections) for `<<'
Problem 2:
.section .text
.org 0xFFE000 /* assuming RAM/addresses mapped at this location */
label:
lea label.w, %a0
Errors thrown for problem 2:
(.text+0xe002): relocation truncated to fit: R_68K_16 against `.text'+e000
(Note that in my linker file, the section .text is defined to be at 0xFF0000. The problem still stands, but that is why the offset is only E000 and not FFE000.)