English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Language > Coders. C/C++

 
 
Thread Tools
Old 07 July 2021, 11:59   #1
deimos
Registered User

 
Join Date: Jul 2018
Location: Switzerland
Posts: 612
Question Generating FFP values at compile time

I'm working with FFP format floating point numbers, using C++ Bartman's GCC environment, cross compiling from Windows.

I have a type,
real
, that's really just a
LONG
with a bunch of overloaded operators to make it appear almost like an inbuilt type.

Everything works, except initialising these objects is awkward. I can't just go:

Code:
    real pi = 3.14159;
I have an a2r function that means I can go:

Code:
    real pi = a2r("3.14159");
which is ok for some things, but really not ideal, and fails in some situations, like in static initialisation of flexible array contents.

At the moment I have a bunch of #defined constants:

Code:
#define r_pi 0xC90FDB42UL
but that's turning out to be a real pain to work with.

Does anyone have any smarter ideas?
deimos is offline  
Old 07 July 2021, 18:21   #2
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 1,398
Well, for Os 3.1.4, we had kinna the reverse problem, namely to let SAS/C accept IEEE single precision constants. The solution there, albeit hacky, was to have a (self-written) preprocessor (not the standard C preprocessor) which took these constants, and converted them to references (i.e. __3_14159), and then later in the build stage, C was compiled to assembler (not object code), and a second script then converted those constants by suitable immediate hex values.

It was really a sort of abuse of the SAS/C compiler chain, and an external "hack" that abused that chain.
Thomas Richter is offline  
Old 07 July 2021, 19:38   #3
Jobbo
Registered User

Jobbo's Avatar
 
Join Date: Jun 2020
Location: Druidia
Posts: 231
I've done something similar.

I wrote a wrapper class around the FFP library. Then pulled some helper functions from elsewhere for conversion from and to ieee floats. I also added some trig/math code as needed.

For my implementation you can declare an FFP with the following helper function:

ffloat value = ffloat_from_ieee(1.2345f);

It's relatively fast but it's still better to do this all upfront so it's only slow for the initial setup.

You can also create ffloat's from ints:

ffloat value = ffloat(1) / ffloat(100); // 0.01

I've shared my class over at: https://github.com/rjobling/ffloat
Jobbo is offline  
Old 07 July 2021, 20:09   #4
deimos
Registered User

 
Join Date: Jul 2018
Location: Switzerland
Posts: 612
Quote:
Originally Posted by Thomas Richter View Post
Well, for Os 3.1.4, we had kinna the reverse problem, namely to let SAS/C accept IEEE single precision constants. The solution there, albeit hacky, was to have a (self-written) preprocessor (not the standard C preprocessor) which took these constants, and converted them to references (i.e. __3_14159), and then later in the build stage, C was compiled to assembler (not object code), and a second script then converted those constants by suitable immediate hex values.

It was really a sort of abuse of the SAS/C compiler chain, and an external "hack" that abused that chain.
Well, that kind of validates one of the ideas I have at the moment, to write a GCC preprocessor, which seems to be a supported, if underdocumented thing.

Trouble mostly is that I'd have to write a preprocessor to run under Windows, and I've never done any Windows development before.
deimos is offline  
Old 07 July 2021, 20:19   #5
deimos
Registered User

 
Join Date: Jul 2018
Location: Switzerland
Posts: 612
Quote:
Originally Posted by Jobbo View Post
I've done something similar.

I wrote a wrapper class around the FFP library. Then pulled some helper functions from elsewhere for conversion from and to ieee floats. I also added some trig/math code as needed.

For my implementation you can declare an FFP with the following helper function:

ffloat value = ffloat_from_ieee(1.2345f);

It's relatively fast but it's still better to do this all upfront so it's only slow for the initial setup.

You can also create ffloat's from ints:

ffloat value = ffloat(1) / ffloat(100); // 0.01

I've shared my class over at: https://github.com/rjobling/ffloat
I've had a quick look at that, and will look deeper tomorrow. It looks like you've tried to do much the same as me, but maybe got further than I have.

One of the problems I have is the static initialisation of flexible array members with that kind of approach ( ffloat_from_ieee or a2f = ffloat from char * ). I'm not sure if it's my code to blame, or a gcc bug. Maybe it would be worthwhile me testing with your approach as well as mine.
deimos is offline  
Old 07 July 2021, 20:35   #6
Jobbo
Registered User

Jobbo's Avatar
 
Join Date: Jun 2020
Location: Druidia
Posts: 231
I don't know what you mean by "static initialization of flexible array members"?

Can you show me an example of what you're doing?
Jobbo is offline  
Old 07 July 2021, 22:28   #7
alkis
Registered User

 
Join Date: Dec 2010
Location: Athens/Greece
Age: 50
Posts: 649
You mean something like that?

http://franke.ms/cex/z/b9vqoo
alkis is offline  
Old 07 July 2021, 22:35   #8
Jobbo
Registered User

Jobbo's Avatar
 
Join Date: Jun 2020
Location: Druidia
Posts: 231
Cool! I hadn't considered trying to get it all to happen at compile time. But that's pretty awesome that it can be made to work.
Jobbo is offline  
Old 07 July 2021, 22:54   #9
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 1,398
Quote:
Originally Posted by deimos View Post
Trouble mostly is that I'd have to write a preprocessor to run under Windows, and I've never done any Windows development before.

First, if it's command line, it's not any different. Just use gcc, and your standard main() to collect command line arguments.


Second, you can always use vamos and write an amiga binary. This is what I did as "pre-processor", but it was supposed to operate in an all-amiga environment anyhow.
Thomas Richter is offline  
Old 08 July 2021, 10:41   #10
deimos
Registered User

 
Join Date: Jul 2018
Location: Switzerland
Posts: 612
Quote:
Originally Posted by Thomas Richter View Post
First, if it's command line, it's not any different. Just use gcc, and your standard main() to collect command line arguments.


Second, you can always use vamos and write an amiga binary. This is what I did as "pre-processor", but it was supposed to operate in an all-amiga environment anyhow.
Vamos seems like a good idea to make sure I'm using the same conversion code regardless of whether I'm converting at compile or runtime.

I think I'll look for something else for the text replacement part, maybe I can make do with a sed script.
deimos is offline  
Old 08 July 2021, 10:48   #11
deimos
Registered User

 
Join Date: Jul 2018
Location: Switzerland
Posts: 612
Quote:
Originally Posted by Jobbo View Post
I don't know what you mean by "static initialization of flexible array members"?

Can you show me an example of what you're doing?
This is what I'm currently doing:

Code:
#include "../real_constants.h"

    static VertexComponentData yVertexComponentData = {
        .numTouchValues = 2,
        .numTotalValues = 4,
        .values = {
            r_0_000,
            r_2_600,
            r_5_500,
            r_1_200
        }
    };
This is what didn't work:

Code:
    static VertexComponentData yVertexComponentData = {
        .numTouchValues = 2,
        .numTotalValues = 4,
        .values = {
            a2r("0.000"),
            a2r("2.600"),
            a2r("5.500"),
            a2r("1.200")
        }
    };
The calls to a2r happen during the static initialisation phase, but the return values get put in the wrong place, overwriting other data.
deimos is offline  
Old 08 July 2021, 11:30   #12
alkis
Registered User

 
Join Date: Dec 2010
Location: Athens/Greece
Age: 50
Posts: 649
Quote:
Originally Posted by deimos View Post
This is what I'm currently doing:

Code:
#include "../real_constants.h"

    static VertexComponentData yVertexComponentData = {
        .numTouchValues = 2,
        .numTotalValues = 4,
        .values = {
            r_0_000,
            r_2_600,
            r_5_500,
            r_1_200
        }
    };
This is what didn't work:

Code:
    static VertexComponentData yVertexComponentData = {
        .numTouchValues = 2,
        .numTotalValues = 4,
        .values = {
            a2r("0.000"),
            a2r("2.600"),
            a2r("5.500"),
            a2r("1.200")
        }
    };
The calls to a2r happen during the static initialisation phase, but the return values get put in the wrong place, overwriting other data.
post#7?
alkis is offline  
Old 08 July 2021, 11:45   #13
deimos
Registered User

 
Join Date: Jul 2018
Location: Switzerland
Posts: 612
Quote:
Originally Posted by alkis View Post
post#7?
Probably needed some explanation and context.

How will that approach work with cross compilation? I'll obviously not be able to use my existing a2r function.
deimos is offline  
Old 08 July 2021, 11:51   #14
alkis
Registered User

 
Join Date: Dec 2010
Location: Athens/Greece
Age: 50
Posts: 649
Quote:
Originally Posted by deimos View Post
Probably needed some explanation and context.

How will that approach work with cross compilation? I'll obviously not be able to use my existing a2r function.
The code in the link initialises an array with FFP values. Isn't that what you wanted?

You have to call the ffpfieee() function and instead of strings supply c++ floats.
alkis is offline  
Old 08 July 2021, 12:12   #15
deimos
Registered User

 
Join Date: Jul 2018
Location: Switzerland
Posts: 612
Quote:
Originally Posted by alkis View Post
The code in the link initialises an array with FFP values. Isn't that what you wanted?

You have to call the ffpfieee() function and instead of strings supply c++ floats.
It's almost what I want - I do want the source to be the text values rather than ieee floats.

But, my question was, how will that work with the cross compilation environment I outlined in

post #1.

The constexpr code needs to be executed, right? But my compiler is running on windows but generating 68000 Amiga code. How can the code be executed at compile time?

Edit:

I'm learning more about this new constexpr thing, and I'm now seeing that it's not code that is executed, it just allows for really complicated expressions to be evaluated, with a whole bunch of restrictions that change every few years. It will be interesting to see if I can parse a string with it.

Last edited by deimos; 08 July 2021 at 12:29.
deimos is offline  
Old 08 July 2021, 12:50   #16
alkis
Registered User

 
Join Date: Dec 2010
Location: Athens/Greece
Age: 50
Posts: 649
The site where you see the code is using a cross-compiler toolchain. So it works in cross-compiler for sure.

But why would you want strings?

Code:
int a[] = {
   foo("3.14159")
};
vs

Code:
int a[] = {
    foo(3.14159)
};
why would you choose string? Aren't floats a cleaner solution?
alkis is offline  
Old 08 July 2021, 13:13   #17
deimos
Registered User

 
Join Date: Jul 2018
Location: Switzerland
Posts: 612
Quote:
Originally Posted by alkis View Post
The site where you see the code is using a cross-compiler toolchain. So it works in cross-compiler for sure.

But why would you want strings?

Code:
int a[] = {
   foo("3.14159")
};
vs

Code:
int a[] = {
    foo(3.14159)
};
why would you choose string? Aren't floats a cleaner solution?
Because ieee sp floats and ffp floats aren't exactly equivalent, they cover different ranges, plus I want to guarantee 100% consistency between the compile time behaviour and the ffp assembly code that I'm wrapping. Using floats may or may not be subjectively cleaner, but strings are what I want, if I can make it work.
deimos is offline  
Old 08 July 2021, 13:26   #18
alkis
Registered User

 
Join Date: Dec 2010
Location: Athens/Greece
Age: 50
Posts: 649
the function ffpfieee is "ffp from ieee"

Check the hex representation here
https://godbolt.org/z/fWbzjTbff
alkis is offline  
Old 08 July 2021, 13:46   #19
deimos
Registered User

 
Join Date: Jul 2018
Location: Switzerland
Posts: 612
Quote:
Originally Posted by alkis View Post
the function ffpfieee is "ffp from ieee"

Check the hex representation here
https://godbolt.org/z/fWbzjTbff
Yes, but ieee floats and ffp floats are functionally different and I don't want to convert between them.
deimos is offline  
Old 08 July 2021, 14:03   #20
alkis
Registered User

 
Join Date: Dec 2010
Location: Athens/Greece
Age: 50
Posts: 649
Quote:
Originally Posted by deimos View Post
Yes, but ieee floats and ffp floats are functionally different and I don't want to convert between them.
There shouldn't be different if your values are within FFP range. If they are not then you have other problems. If they are, then the conversion should work.

Last edited by alkis; 08 July 2021 at 14:10. Reason: typos
alkis is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Generating an accurate Paula period table 8bitbubsy Coders. General 55 07 September 2020 21:04
Wanted: C source for converting gcc (linux) float to FFP alkis Coders. C/C++ 5 16 August 2020 02:39
Integers vs floats (FFP/Sing/Doub) + printf() guy lateur Coders. Asm / Hardware 63 18 July 2017 17:57
WinUAELoader: generating single game .uae? Telegattone support.WinUAE 1 27 December 2016 12:28
Software for generating screenshots and videos Edi (FZ2D) Retrogaming General Discussion 5 08 April 2010 23:34

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 07:10.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2021, vBulletin Solutions Inc.
Page generated in 0.12028 seconds with 13 queries