Page 1 of 1

How to deal with DIV/DIVU needs in ".set noat" cod

Posted: Mon Sep 07, 2009 10:06 am
by dlanor
In the EE MIPS instruction set some opcodes are treated as macros, even though they are implemented opcodes at hardware level, simply because the assembler will not entrust a human being with the task of following the special rules involved (pipelining and overflow issues).

However, this also has the consequence that it becomes impossible to use such arithmetic inside asm sections that need ".set noat" to protect the $at register from being affected. Attempts to do so simply result in warnings about the macro use leaving me confused as to what I can then expect from the binary.

Several possibilities exist:
1: The macro failure causes NO opcodes to be generated for that source line. This will completely bug out the program.
2: The macro is expanded, but without the $at references. This may cause bugs, depending on the specific macro.
3: The macro is ignored, instead using only the specified opcode. And this is of course what I want.

What I now wonder is if I really get that third alternative or not, and if the assembler contains any other (to me unknown) directive to inhibit the macro expansion completely for a specified section, so that the DIV/DIVU opcodes can be used without expansion, resulting only in their raw opcodes being generated for the binary, leaving the pipelining considerations and overflow testing to the human programmer. That would of course be better, as I also want to suppress the 'macro' warnings for code sections where I intentionally want to use only the raw CPU instructions.

So is there such a method ?
Or is the GCC+gas combo unable to allow a human such total contol ?

Edit: On a related note: When the assembler gives warning messages related to inline assembly in a C program, that message always relates to the line number of a temporary ".s" file which will already be deleted when the 'make' process stops.

Is it possible to prevent this deletion somehow, so as to allow the causes of a warning to be inspected in the temporary ".s" file ?

Best regards: dlanor

Posted: Tue Sep 08, 2009 12:49 am
by J.F.
Use -S -c to get the .s file.

Posted: Tue Sep 08, 2009 11:21 am
by Fakeuser
I always backup $at manually:)

Code: Select all

sw $at,0xfff0(sp)
.....
.....
lw $at,0xfff0(sp)

Posted: Tue Sep 08, 2009 8:00 pm
by dlanor
J.F. wrote:Use -S -c to get the .s file.
At what point can I do that. Inside the makefile somewhere ?
And if so, where do I need to insert those strings ?

Using them in a command given after a 'make' attempt is not possible, because by that time the temp file has already been erased.

Edit: Let me clarify that this problem applies only to inline assembly sections inside a ".c" file, as there is obviously no problem inspecting normal ".s" files. But for the inline asm sections there are only temporary ".s" files, erased automatically after the 'make', even if there were errors motivating that the files be kept for inspection.

Can the flags you mentioned modify that behaviour ?
Fakeuser wrote:I always backup $at manually:)

Code: Select all

sw $at,0xfff0(sp)
.....
.....
lw $at,0xfff0(sp)
My problem was never about how to preserve the 'at' register, as that can be done by many methods. But I really wanted to know what code the compiler+assembler produces for such a case.

Is it just the single opcode of a "div"/"divu" instruction, as seen in the opcode docs, or is it the macro expansion which would be used in a normal asm section (or after ".set at").

Edit: I guess I'll have to make a small experiment to find that out for sure.

And more importantly, I also asked about whether or not there is any command to give a user total control of the opcodes, by completely disabling all 'implicit' macro expansion. If such a command is available then it makes possible a higher degree of 'hand optimization', which is impossible to achieve if the compiler and assembler combo lacks that feature.

I'm a long-term asm coder but never worked with MIPS processors or MIPS tools before the PS2 stuff, so I'm a bit shocked at not having found any way for a human being to assemble or compile code with total control of what is generated (except by poking a binary array with pure numbers). Instead the tools reserve such control for themselves only, and seem very 'stingy' about sharing that power with us humans...:(

With all other development tools I've used, for several other processor 'families', there was always some way to override or work around any implicit macro code generation. (Which many simply didn't have, at all.)

Best regards: dlanor

Posted: Wed Sep 09, 2009 2:45 am
by J.F.
-S -c would be part of CFLAGS used by gcc/CC in the makefile. The combination tells gcc to output .s files and then stop. Just add them to wherever you set other flags, like -O2 or -Wall.

Posted: Wed Sep 09, 2009 7:45 am
by dlanor
J.F. wrote:-S -c would be part of CFLAGS used by gcc/CC in the makefile. The combination tells gcc to output .s files and then stop. Just add them to wherever you set other flags, like -O2 or -Wall.
Ok, I had a hunch it would be the makefile, but I wanted it confirmed.
But if gcc stops after making those files, then this implies that I will never get them assembled in that session, and thus won't get to see the warning messages.

So to make use of this method I would have to first make one compilation without those flags, so as to get all the error messages. And then I'd have to edit the makefile (or use another pre-edited) to use it with those flags so as to generate the ".s" files where I can search for the reported line numbers of the warnings.

That's a rather roundabout method, especially for so famous a compiler as gcc...

Fortunately my immediate problems that led to me making this thread have been solved by other means, though I still had to do it without the full control over implicit asm macros that I wanted.

But thanks for taking an interest, at least I now know how to get the source files holding the reported lines of inline asm, for cases in the future when similar problems arise.

Best regards: dlanor

Posted: Wed Sep 09, 2009 5:34 pm
by misfire
dlanor wrote:But if gcc stops after making those files, then this implies that I will never get them assembled in that session, and thus won't get to see the warning messages.
Take a look at the standard build rules for EE binaries:
http://bitbucket.org/misfire/ps2sdk/src ... mple#cl-37

You can see that the object files are always built with the -c option when you compile *.c files, for instance.

I guess you simply have to add -S to EE_CFLAGS as suggested by J.F.

Posted: Wed Sep 09, 2009 5:49 pm
by Herben
If you want to stop GCC from deleting temporary source files try adding "-save-temps" to your CFLAGS.

In order to make GAS output a literal DIV/DIVU instruction instead of expanding it into a multi-instruction macro, you need to specify $0("zero") for the "destination" register like "div $0, $3, $4".

Posted: Thu Sep 10, 2009 11:48 pm
by dlanor
Thanks, guys. I'll try out your suggestions to find what suits me best.

Best regards: dlanor

Posted: Mon Sep 28, 2009 3:42 am
by dlanor
I have now had occasion to try the suggestions above, of using -S and -c in the EE_FLAGS definition of my makefile (both separately and combined), only to note that it has no effect whatsoever on the temporary source files used for inline asm blocks.

I suspect that you may have misunderstood my problem earlier, believing that it had anything to do with normal assembly source files, which is not at all the issue here.

I need to inspect errors in the temporary source files created automatically by the compiler in response to inline "__asm__" blocks in C source files.

However, whenever I get those error messages and open the TEMP folder they refer to, those source files are already deleted from it. And this happens identically with those EE_CFLAGS you guys recommended.

That deletion is what I need to stop, and those -S and -c flags do not have this effect.

I find this whole situation quite absurd really. First GCC prepares an error message, meticulously telling me the precise path and filename used, and even provides me with the exact line number to let me pinpoint the error in the auto-generated source file. But immediately before displaying this message it then deletes the file described in the message, thus making it impossible to inspect the error for debugging.

This is nothing less than pure insanity...
(That deletion should be stopped automatically on any assembly error)

Edit:
Anyway, I have now found that the "-save-temps" flag does save the files I need, though not then in the TEMP folder, but in the current project folder, which suits me even better. So my immediate problem is solved. But I still think GCC is insane to by default delete files needed to track down a problem it reports.

Best regards: dlanor

Posted: Tue Sep 29, 2009 10:05 am
by kalms
To sum up, if you do the following three operations:

Code: Select all

	.set	noat		-- disallow assembler's own use of $at
	.set	noreorder	-- assembler will not reorder instructions
	.set	nomacro	-- disallow use of macro instructions
... then gas will interpret your code as-is and yell whenever you attempt to use any synthetic instructions. You can now pipeline code to your heart's content and need to watch out for any delay slots yourself.

For more details, check out the book named "See MIPS Run". Some/all of it is available on Google Books. Particularly Chapter 8 will be of interest to you.