Disable ld -> ldh optimization
#243
Comments
|
Since this would break legacy codebases, I'd hardly see the benefit. While it would certainly be useful to be able to opt out of this optimization, it would probably do more harm than good to do it for |
|
In that case, I think that we should have a command line option to disable it in disassemblies. I really don't like the idea of adding aliases for instructions when the issue is not the mnemonic, but some strange behaviour of the tool. I'd rather be able to disable the strange behaviour. |
|
You could call the absolute to relative conversion in (And it's easy to solve all of these issues with macros, but it would be much better if we didn't have to.) |
|
It's not really strange, it's what you expect as a developer. When you use What's the real use-case for |
|
I've used And I've run into corner cases in macro definitions that would be handled much more cleanly without extra labels. You normally want the conversion, but there are odd edge cases when you don't. You normally want |
|
I don't like that idea. A label is always clear. a Regarding the |
|
I think the argument regarding As far as the |
|
But the current tool doesn't prevent you from doing what you want. You can always use '@' or a label. In any case, using '@' is unmaintainable:
The previous one is obviously more clear than this:
And if you want to change the number of instructions that it skips, you have to calculate it by hand, which is a very easy way to introduce bugs. And if you are taking a look at the code for the first time, you will have to think about it a bit before understanding where it is jumping. And when you understand it, you will start to think "why doesn't this code have a simple label that anyone can understand?". Regarding the Symbols can be relocatable or not. A relocatable symbol won't be optimized, a constant one will. Something like this (all the code is in the same file) should make rgbasm optimize the
If you have the sections in two different object files, it won't be optimized. That's why I want to disable this optimization, a simple reorganization of the code might make the assembler optimize them or not, which is inconsistent, and not obvious to someone using the tool. |
|
Regarding Regarding Since there are at least two real codebases that use |
|
But that makes
It's much clearer to have a flag to just keep it working as it is, or don't do anything. Old code will behave the same way as it has always done, and new disassemblies know that they will always get the opcode they want. But that's another problem. If suddenly there is a new opcode that doesn't have that -2 offset, you need to know that the new opcode doesn't have that -2 offset. It forces you to check the documentation... and that's just to see how a jump is supposed to work. It's just not a good idea. Assembly is supposed to have a simple syntax because it's hard to understand. This suggestion looks like a hack that is going to make things even harder to understand because now you need to know which one of the 2 behaviours you are going to get, the one of '@' or the one you are proposing. This is not obvious to someone looking at the code unless that person has done that before. Labels are unambiguous, and literally anyone that has ever written code would understand that 2 codebases is anecdotal evidence. I actually discussed this with a colleague of mine and he immediately said that labels were the only way to do this properly and that if he had found your code in a code review he would have rejected it right away. And I would have done the same. If I can't see where a jump is jumping right away, it's not clear enough. And what you are asking for forces you to know the size of the instructions, which isn't impossible in the case of the GB, but is completely unnecessary when you can achieve the same effect with a simple label. In short, if you want to do this in your projects, feel free to create a macro based on Also, regarding the other codebase... He is only using it because |
|
Sorry to interrupt, but back to the original issue at hand... I appreciate that disassemblies require as much control as possible, so explicit However, when developing new projects, I think it’s advantageous to have this optimisation; for example, if you decide to later optimise some code by moving a commonly-used variable from WRAM to HRAM, you would have to manually go through and change all the I agree that the current behaviour across files is inconsistent, but I think it’d be a bit of a cop-out if we fixed the inconsistency by just removing the optimisation. Making a So:
(I hope this is less provocative than the discussion above! |
|
The problem with #229 is that the linker has to be involved, sections would need the ability to be resized, and resizing sections creates all sort of problems because the linker was never meant to do that (make patches moveable, implement recursive placement of sections...). It's simply not worth it when the coder can just use That's why what I want to do is to simply have a flag to disable/enable the current behaviour, making it even more clever involves a huge change in the linker. That is also why I've decided to drop any kind of optimization related to |
|
The most important thing with this is keeping backwards-compatibility ( Disabling behavior is OK for disasms, yadda yadda. Nothing to add there. Enforcing behavior is better for development (as @Ben10do said) AND disasms (the example I have in mind right now is Furthermore, toggling between |
|
Ultimately, that falls back into the "section size not fixed" pitfall. Do remember that the address passed to |
|
I agree that the assumption should be a 3-byte |
|
Replacing an Which is the current behavior. |
|
No, the current behavior is if the address passed is a constant known at compile time. My suggestion is to extend that behavior to addresses that are known at link time. This would make the current behavior more consistent (namely, the optimization would be independent from the file HRAM variables are declared in). |
|
Something cannot be simultaneously calculated at link time and known prior
to linking. Which one is it?
EDIT: I'm obviously assuming that "known prior to linking" means "known before linking begins". If it means "known before linking ends", we have the linker choosing between ld/ldh, which falls into the "linker resizes sections" pitfall (as changing an ld into ldh requires deleting a byte).
|
|
What I meant is, a huge limitation currently is that if HRAM labels are declared in another file, the assembler will optimize. Otherwise, it won't, since it doesn't have the information. |
|
But that is the problem, any optimization done by the linker implies resizing sections. |
|
…And we're back at square one. I don't deny that having the linker be able to resize sections, and therefore do any space-saving optimisation, will be tricky. As a result, I completely understand why @AntonioND thinks it's 'simply not worth it' (especially in the short term). However, as I think many users (myself included) would find such optimisations useful, I don't think that this means we should rule it out for RGBDS's future. I'd gladly look into doing this, if I find time between work and my own projects; but there's nothing to stop any other contributor from familiarising themselves with rgblink's current design and what's necessary to allow it to resize sections. |
|
Since we're back at square one, I think it's important to emphasise at this point that such behavior should always require an enabling flag. The linker resizing sections would be both backwards-incompatible and very non-intuitive, which is why it should not happen by default. That being said, optimizations are always helpful, of course. |
|
But it's not even as easy as just resizing sections. For example:
For this to work, the assembler needs to know that the subtraction isn't defined at assembly time because the linker may optimize it. You need to make rgbasm create a patch for that expression instead of calculating the difference at assembly time. Which means that if you enable the optimization in the linker but not in the assembler you will have trouble. And it's not easy to detect when the patch is needed... |
|
Given that there are already cases where the assembler cannot compute such an expression, for example :
It's not a big stretch, imo. |
|
As far as I recall from my experiences with Prism, that just fails if the assembler cannot figure it out. |
|
That's the resizing sections problem again. |
|
@aaaaaa123456789 -> I find it bumming that this fails to compile. It's valid, there are uses cases, etc. |
|
It fails to compile because it assumes that the assembler can leave that value as undetermined for the linker to calculate. And sure, the linker can do that, but the only changes that the linker can do is to replace values in a section. For example, for What you want to happen to
In short, this is not a simple addition, this is a fundamental change to the linker. I don't know of any toolchain that allows this kind of behaviour (WLA DX doesn't, for sure, but I'm talking about any assembler for any platform, I'm curious). |
|
I remember running head-first into this issue in #149, when the behavior wasn't a hard failure and the assembler tried its best to figure out the size — and obviously got it wrong. I wonder if the That being said, this chain effect is exactly why letting the linker resize sections at all is a bad idea — I've seen a macro expand into |
|
Well, seeing that this discussion has died, I think it's a good time to close this issue (it has been fixed in #246). If someone wants to keep discussing, feel free, of course. |
In the Game Boy you usually want to have as much control over the final output of the ROM as you can, specially in disassemblies. This automatic optimization at assembly time is pointless, there are only a couple of cases in which it is useful, and it's not even consistently useful (if you declare a label inside a
HRAMsection in a different object file, rgbasm can't optimize anything).I'm thinking about removing it. I'm not sure if it is worth keeping a command line flag to disable it, doing that by default or simply remove it forever.
Opinions?
The text was updated successfully, but these errors were encountered: