Inline assembly: movsa / movda missing?
jac_goudsmit
Posts: 418
Hi guys,
I know there is a "MOVA destination, #sourceaddress" pseudo-instruction which should be used to store cog addresses somewhere. The special instruction is needed to make the linker divide the source expression by 4 to obtain a cog address (32 bits per location).
But my code (a fairly long block of inline assembly in a .cogc module) contains some "MOVS destination, #sourceaddress" and "MOVD destination, #sourceaddress" instructions, and they result in the dreaded "relocation truncated" error. I'm thinking there should be MOVSA and MOVDA instructions that do the same as MOVA: divide the source address by 4.
Code fragment: (Note: I know this fragment can be coded differently but the function of the code is not the point here, just the problem that it's impossible to put a perfectly legal instruction in the inline assembly code)
(PS my code is less than 200 instructions (based on line count of inline assembly) so the relocation truncated error is not because I'm overflowing a cog)
===Jac
I know there is a "MOVA destination, #sourceaddress" pseudo-instruction which should be used to store cog addresses somewhere. The special instruction is needed to make the linker divide the source expression by 4 to obtain a cog address (32 bits per location).
But my code (a fairly long block of inline assembly in a .cogc module) contains some "MOVS destination, #sourceaddress" and "MOVD destination, #sourceaddress" instructions, and they result in the dreaded "relocation truncated" error. I'm thinking there should be MOVSA and MOVDA instructions that do the same as MOVA: divide the source address by 4.
Code fragment: (Note: I know this fragment can be coded differently but the function of the code is not the point here, just the problem that it's impossible to put a perfectly legal instruction in the inline assembly code)
__asm__ __volatile__ ( " movs jmpins, #destination \n" // Error: relocation truncated " nop \n" "jmpins \n" " jmp #0 \n" // destination patched with movs instruction ... "destination \n" // more code here :::);
(PS my code is less than 200 instructions (based on line count of inline assembly) so the relocation truncated error is not because I'm overflowing a cog)
===Jac
Comments
I have used movs, movi, and jump tables, and they all work fine with a .cog_ram directive at the top (I never use mova). I have an example of this type of code in this thread: http://forums.parallax.com/showthread.php/142441-Native-assembly-files-(*.S)-in-propgcc.
David
I added a ".cog_ram" directive to the top of my inline assembler and that made the errors go away. I'll verify the assembly output to see if the result is correct. Thanks!
I've been considering switching to a .S module for this part of my project, and it's getting more and more tempting (not in the least because I was also running into the hard limit of 30 arguments per assembly fragment), but I want to stick to inline assembly as long as I can so that I can write an article about it on the PropGCC. I think there are probably many small projects out there that would benefit from combining small fragments of very fast assembly that runs on the same cog as other code in C/C++. When using Spin, it's not possible to make this combination, and when using a .S module, the code gets physically separated in multiple files which makes the feature less obvious.
I didn't really want to use those MOVA/MOVSA/MOVDA instructions either (it's too easy to make mistakes). I wonder if .cog_ram should be the default and the MOVA instruction should be deprecated.
Either way, I still think if there is a MOVA there should probably also be a MOVSA and a MOVDA.
Thanks again!
===Jac
Eric