-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Operator & with negative offset #34
Comments
Hello Sergio, I find this a bit hard myself, but I'm afraid the short answer is "no", you cannot trust (load8 &-1) etc. inside expressions. As you have seen, the main reason for this is that there is some reordering of operations. I suspect it might also interfere with the implementation of some pseudo-instructions. Currently, there is no way to safely duplicate elements on the stack inside an expression. If you want to do this for efficiency, you should use statements instead. There are ways to solve this in the assembler, but it is not much time left in the project for such adjustments. If this is important to you, you should escalate the issue (to the Oscar and Bjarte or to Ole). |
Thank you for you answers both the short and the long ones. :-D The reason why it is labeled as a 'question' is because: first, it is not important itself (we can handle it by emitting statements as you propose) and, second, I had no idea if negative offset were "updated" as well as positive offset, as these later ones are in fact updated regardless there are any reordering of operations or not. We use extensively the negative offset in operator '&' in instruction I my experiment (where this issue comes from) there are no pseudo-instructions involved, only labels. I treat labels as if they fit in a word as each label were a constant or the result of a plus over to words: set_pc+const. This is what I thought: I am aware that there is not much time, that is why I was a bit surprised by the last modifications of the IVM native instruction set. |
|
Hello Ivar, I would like to thank you for your work with the ivm assembly language. The syntactic sugar you designed allowed us to choose the aspect of the C compiler production, and now with our delivery of the Yet Another IVM64 C Compiler, you can also choose the final aspect of your assembly, object and asm-executable output files as all of them are assembly. Regarding this already unclosed issue (I think we should close it soon), I share with you the above snapshot with the result of the compilation of a very simple C program (left) and the compiled output in two flavours: natural (centre) and sugar (right). As you can see, in natural flavour (and also light flavour, statement based with or without pseudo instructions) it is easy to duplicate the common expression once it is computed at the top of the stack (just In either case, the result is correct (both without the negative offset), a few steps more or less when executed. And perhaps the readability is worse with negative offsets. I agree with you that this seen more or less affordable when only Perhaps in the future, some one decides if this way deserves to be walked. Again, thank you Ivar, and thank all the immortal machine project people. |
Thanks for the update, Sergio (and sorry about the late reply). I think we should leave this question/suggestion open for now since it makes a lot of sense. If someone decides to continue the development (e.g. Piql), then they can decide if it is something they would like to prioritize. |
The operator & is used, in sugar expression of instructions, to refer to a stack location. For example &0 is the position in memory of the last pushed word before the instruction containing such sugar expression.
Sometimes, it is useful to duplicate an element in the stack after loading it. We have tested that &-1 refer to the position in memory of the first element in stack pushed by the sugar expression. The example instruction:
push! (* (load4 (load8 &0)) (load4 &-1))
makes and indirect load of a variable (x) whose address is at TOS (top of stack), replicates its value and then multiply them, leaving the result (x * x) on the stack (just below the address of x). If there are intermediate pushes, adjusting the negative offset is required. Instructions below should be equivalent for (x * x + 1):push! (+ (* (load4 (load8 &0)) (load4 &-1)) 1)
push! (+ 1 (* (load4 (load8 &0)) (load4 &-2)))
but the first one give a more compact and faster binary.
In the code below, this situation changes because the assembler reorganized the pushes, placing PC (get_pc) before the first load4 (perhaps because of the label, being a PC relative address). The assembler then changes &0 from (load8 &0: get_sp+load8) to (load8 &1: get_sp+push 8+add+load8), but it does NOT change &-1 to &-2.
Executing the above code with
ivm as-run -t
, the duplicated word is not the number 7, but the value pushed byget_pc
, which is not the intended.If the label (get_pc+push1+add) is the last pushed (just before add+load8 as the expression suggests) the reference &-1 (to the location of the previously pushed word) will be correct and the binary will be better (more compact and faster). But, leaving get_pc as the first instruction (after .watch) of the binary we have to use &-2 which is not coherent with the written expression, and also extra 'push' and 'add' instructions appear.
Can we trust operator & with negative offset in expressions including labels?
The text was updated successfully, but these errors were encountered: