-
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
Fptest64 #8
base: fptest
Are you sure you want to change the base?
Fptest64 #8
Conversation
looks like some style issues need to be fixed :) |
Yep, I found a dangling space in specialize.h. It's fixed now and all tests pass! |
OK, so i looked a bit closer... Unfortunately i see one or two problems with this. I really appreciate the effort - however, i'd rather keep the unmodified code in my branch as long as the modifications are not exactly like we need them.
: another thing to consider is, that at some point in the future, the float support should be extended so it can make use of eg a library with 16bit floats. This would be a lot easier to handle, if floats and doubles share the same ABI (ie no passing of doubles via pointers), because then the existing 32bit float library code can be used for the doubles in that case.
|
Unfortunately this topic as well beyond my skill level. I won't be able to provide any helpful assessment 😞 |
Hi Bob! I agree with everything you're saying and can see why you wouldn't want to accept the pull request in its current state. I'm happy to change the float64 functions to exactly match the float32 functions (i.e., making the a = a X b case work correctly). I think the trickier thing is the problem you brought up first -- for 64-bit floats to be used in functions, there needs to be a way to pass 8-byte values between functions. If the compiler secretly passes pointers instead of the full 8 bytes of the float64, a user could do something like this: #include <stdio.h>
double modify_incoming(double x) { // here, a pointer to x is passed instead of a copy of x.
x += 5.0;
return x;
}
int main() {
double x = 8.0;
double y = modify_incoming(x);
printf("%f, %f\n", x, y);
// this should print "8.0, 13.0", but it will actually print "13.0, 13.0".
return 0;
} To solve this problem, we would either need to extend the calling convention of cc65 to allow passing 8-byte values as arguments and return values (see my previous post for ways to do that), or we would need to do the code generation such that, when doubles are passed, a temporary variable is put on the stack to use in place of the incoming argument. For example, the user code above could generate code with the necessary stack-allocated temporary variables internally, like so: #include <stdio.h>
void modify_incoming(double *dst, double *x) {
double _temp = *x; // a temporary variable is inserted here to hold x's value.
_temp += 5.0;
*dst = _temp;
}
int main() {
double y;
double x = 8.0;
modify_incoming(&y, &x); // this is changed to pass by pointer.
printf("%f, %f\n", x, y);
// this should print "8.0, 13.0", and now it actually will.
return 0;
} Overall, I think this would make code generation for 8-byte values complicated. I think updating the calling convention to allow for 8-byte argument passing would be the cleanest solution, but I don't think I can do that by myself. I'd be happy to help with that as much as I can, but that seems like a big increase in the scope of the project compared to implementing 32-bit floats. For now, I can get the float64 functions to work safely with the a = a X b case, and then the issue of fully implementing doubles in the compiler could be addressed later. What do you think? |
For the reasons already mentioned, i think it only makes sense without that magic converting to pointers (That will create more problems than it solves). |
Fptest64 was branched off of fptest. It is identical except that it modifies the 64-bit floating point routines from Berkeley softfloat 2 to use pointers instead of values, allowing these to be compiled by cc65. All functions that previously took a
float64
as an argument now take a*float64
as an argument. All functions that returned a struct (either a float64 or a commonNaNT) now accept an additional argument, dst, which is a pointer to memory for returning the value.There's also one small change in roundAndPackFloat32 that fixes a problem I encountered in small test programs on the Commodore 64.
Note that this differs from the approach for returning commonNaNTs in the 32-bit floating point routines. Those return a pointer to static memory containing the commonNaNT, which means each invocation of the function clobbers the return value of the previous invocation. The approach used here trades inconvenience for safety by avoiding this clobbering.
Note also that, to reduce memory copying, some functions modify the pointed-to return memory during the function and will produce incorrect results if a memory location is used both as an input argument and a return location. To avoid problems, don't do this:
Instead, do this:
The functions included here should work, though they require more testing. Fully integrating them into the compiler will require further work:
For this last problem, I can think of 2 solutions:
I am not that familiar with the compiler, but I'll keep working on these problems for a future pull request.
-Jim