-
Notifications
You must be signed in to change notification settings - Fork 18
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
be-codegen-6800.c be-code-6800.c Ideas for making signed/unsigned char comparisons more efficient #162
Comments
For the first part instead of rewriting you can now add backend_byte.c to that target and call
That will go through the tree and work out what it knows can be done 8bit. It will change the size on most of them to byte but will retain the size and set the BYTEABLE flag on any where the real size matters but they can be done 8bit - eg condition codes, T_BANG, and T_BOOL. Search for BYTEABLE in the 6502 tree for examples. For conditions the compiler sets CCONLY on the top node before a branch. Z80 uses this and knowledge of what operators can be done on condition codes to do subtrees that way (see be-codegen-z80:propogate_cconly() ). The only nasty case to handle is that T_BANG or T_BOOL of a condition code only can need to be converted back into a boolean in a few corner cases. Z80 just has a little helper __cctonot that deals with it. |
I tried BYTETABLE. When processing with cmp_direct, the terms on the right side can be omitted, but the terms on the left side have already been processed at the time of cmp_direct, so the unnecessary CAST could not be omitted. Below is the output result of the code used for testing.
compiled result.
I'll think about it a bit more. |
The byte code knows about some char/char comparisons but not about most char - constant (and especially unsigned char v constant) ones. That is the right place to add those tricks so that they are shared between targets I think. |
I tried backend-byte.c. It looks good. I need to consider the scope of BYTEOP further. test program:
object code (while loop).
object code (if statement).
When T_PLUS/T_MINUS/T_STAR are enabled, subscripting of CCHAR/UCHAR arrays fails. Subscript must be CSHORT.
Simple branches that do not require values are optimized using a peep hole by taking advantage of the fact that they have the shape Lxx_y.
|
one more.
sample:
|
Made some more changes to backend-byte to try and cover your ideas. The + - * case is correct in the code though. If it's generating wrong 6800 code then there's a bug in the backend that's being triggered by something being byte sized it was not expecting or by mishandling of casting perhaps ? If you copied the 6502 code there was a cast mishandling bug in there I fixed
and that plus a couple of other fixes makes it handle the case correctly on 6502 as far as I can see |
The reason the array reference is wrong is because T_NAME was being added in bytes. I fixed that, but other things may need to be fixed.
|
T_EQ is a typo yes. T_NAME is byte convertible if the stuff using it is byte sized so the problem is somewhere else. I don't see it on 6502 so I still suspect the bug is in the 6800 codegen |
If both can be compared as char, gen_rewrite rewrites the AST to reduce T_CAST. This allows cmp_direct to generate efficient code.
The problem with this method is that the code becomes more complicated as the number of patterns that can be made more efficient increases (global variables can also be made more efficient).
I'm also concerned that gen_rewrite and cmp_direct perform similar comparisons. However, cmp_direct alone was unable to remove unnecessary casts, so the code looks like this.
Now, if we make it more efficient like this, the jsr boolXX/jeq after cmpb can become jXX. To do this, I need to know that this comparison does not require a result (0/1). How can I know that?
sample program:
compiled asm at while loop.
if statement.
The text was updated successfully, but these errors were encountered: