Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #161725 > unrolled thread
| Started by | Robert Finch <robfi680@gmail.com> |
|---|---|
| First post | 2021-07-07 16:39 -0700 |
| Last post | 2021-09-30 18:04 +0200 |
| Articles | 19 on this page of 59 — 11 participants |
Back to article view | Back to comp.lang.c
naked switches Robert Finch <robfi680@gmail.com> - 2021-07-07 16:39 -0700
Re: naked switches Bart <bc@freeuk.com> - 2021-07-08 01:26 +0100
Re: naked switches Kaz Kylheku <563-365-8930@kylheku.com> - 2021-07-08 01:57 +0000
Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-08 09:16 +0200
Re: naked switches Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-07-08 01:00 -0700
Re: naked switches Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-07-08 03:25 -0700
Re: naked switches Robert Finch <robfi680@gmail.com> - 2021-07-08 06:58 -0700
Re: naked switches Bart <bc@freeuk.com> - 2021-07-08 15:52 +0100
Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-08 17:52 +0200
Re: naked switches Bart <bc@freeuk.com> - 2021-07-08 17:51 +0100
Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-09 10:01 +0200
Re: naked switches Bart <bc@freeuk.com> - 2021-07-09 11:09 +0100
Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-09 13:14 +0200
Re: naked switches Manfred <noname@add.invalid> - 2021-07-09 15:35 +0200
Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-09 16:51 +0200
Re: naked switches Manfred <noname@add.invalid> - 2021-07-09 18:23 +0200
Re: naked switches Bart <bc@freeuk.com> - 2021-07-09 16:07 +0100
Re: naked switches Manfred <noname@add.invalid> - 2021-07-09 18:41 +0200
Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-10 11:02 +0200
Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-09 19:20 +0200
Re: naked switches Robert Finch <robfi680@gmail.com> - 2021-07-09 10:46 -0700
Re: naked switches Kaz Kylheku <563-365-8930@kylheku.com> - 2021-07-09 19:56 +0000
Re: naked switches Bart <bc@freeuk.com> - 2021-07-09 22:01 +0100
Re: naked switches Robert Finch <robfi680@gmail.com> - 2021-07-09 15:07 -0700
Re: naked switches Bart <bc@freeuk.com> - 2021-07-09 23:30 +0100
Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-10 12:17 +0200
Re: naked switches Robert Finch <robfi680@gmail.com> - 2021-07-08 10:18 -0700
Re: naked switches Bart <bc@freeuk.com> - 2021-07-08 18:43 +0100
Re: naked switches Robert Finch <robfi680@gmail.com> - 2021-07-08 15:32 -0700
Re: naked switches Kaz Kylheku <563-365-8930@kylheku.com> - 2021-07-08 17:47 +0000
Re: naked switches Robert Finch <robfi680@gmail.com> - 2021-07-08 15:45 -0700
Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-09 10:27 +0200
Re: naked switches Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-07-09 11:13 +0100
Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-09 13:30 +0200
Re: naked switches Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-07-11 00:39 -0700
Re: naked switches scott@slp53.sl.home (Scott Lurndal) - 2021-07-11 14:06 +0000
Re: naked switches Robert Finch <robfi680@gmail.com> - 2021-07-11 08:01 -0700
Re: naked switches Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-07-16 03:53 -0700
Re: naked switches scott@slp53.sl.home (Scott Lurndal) - 2021-07-16 14:47 +0000
Re: naked switches Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-09-30 06:09 -0700
Re: naked switches Robert Finch <robfi680@gmail.com> - 2021-09-30 07:03 -0700
Re: naked switches Bart <bc@freeuk.com> - 2021-07-09 13:44 +0100
Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-10 13:28 +0200
Re: naked switches Bart <bc@freeuk.com> - 2021-07-10 13:04 +0100
Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-10 15:39 +0200
Re: naked switches Bart <bc@freeuk.com> - 2021-07-10 15:08 +0100
Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-10 17:34 +0200
Re: naked switches Bart <bc@freeuk.com> - 2021-07-10 17:47 +0100
Re: naked switches Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-07-11 00:57 -0700
Re: naked switches Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-07-16 03:51 -0700
Re: naked switches Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-07-08 11:40 -0700
Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-09 10:38 +0200
Re: naked switches Kaz Kylheku <563-365-8930@kylheku.com> - 2021-07-08 17:33 +0000
Re: naked switches scott@slp53.sl.home (Scott Lurndal) - 2021-07-08 17:47 +0000
Re: naked switches Kaz Kylheku <563-365-8930@kylheku.com> - 2021-07-08 17:58 +0000
Re: naked switches scott@slp53.sl.home (Scott Lurndal) - 2021-07-08 19:13 +0000
Re: naked switches Kaz Kylheku <563-365-8930@kylheku.com> - 2021-07-09 02:30 +0000
Re: naked switches David Brown <david.brown@hesbynett.no> - 2021-07-09 10:41 +0200
Re: naked switches Bonita Montero <Bonita.Montero@gmail.com> - 2021-09-30 18:04 +0200
Page 3 of 3 — ← Prev page 1 2 [3]
| From | Robert Finch <robfi680@gmail.com> |
|---|---|
| Date | 2021-09-30 07:03 -0700 |
| Message-ID | <afbef2eb-dde1-4bfd-bb88-4419eb1c0733n@googlegroups.com> |
| In reply to | #162877 |
I have modified my compiler to recognize when switches are one-hot powers of two and it uses the BBS instruction if available. No special syntax required for switches.
I added syntax to enums however to allow using an enum to define one-hot values.
enum (2*) { a, b, c, d, e};
Assigns the values 0,1,2,4,8 to a,b,c,d,e respectively.
The (2*) is the exponential increment spec. (3*, 4*, etc is also possible).
enums in my compiler also allow the increment to vary
enum(3) { a, b, c, d, e}; for instance increments the enum value by 3 for each symbol.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2021-07-09 13:44 +0100 |
| Message-ID | <sc9gav$iln$1@dont-email.me> |
| In reply to | #161774 |
On 09/07/2021 09:27, David Brown wrote: > On 09/07/2021 00:45, Robert Finch wrote: >> On Thursday, July 8, 2021 at 1:47:12 PM UTC-4, Kaz Kylheku wrote: >>> A macro can do this: >>> >>> a = BIT(b,10,1); >>> >>> and works everywhere. What you need is a typeof extension to make it >>> work with different integer types while retaining efficiency, otherwise >>> you're looking at making it assume 64 bit, or saddling it with a type >>> name argument. >> >> One should not have to write macros for commonly used language elements. > > Your extension is not commonly used, because it only exists in your > tool. People who need to do a lot of bit slicing and don't like masking > and shifting (or struct bit-fields) should not have trouble defining: > > #define BIT(x, top, bottom) \ > (((x) >> (bottom)) & ((1llu << ((top) - (bottom) + 1)) - 1)) > > Yes, the parenthesis you need for macros are ugly, but you only need to > get it right once, and now you can read your bit-fields. > > Having said that, it is not at all unreasonable for an embedded compiler > to ship with extra headers, which would be an excellent place to put > macros like this for user convenience. It would be simpler and clearer > to C programmers who are not used to your extensions. This is the > technique used by other embedded compilers. > > I'm not saying the extension is not useful, or bad in itself - but I > dislike adding extensions when it is perfectly possible to get the same > results without changing the language. Then there would have been no need for the [] indexing syntax either. You'd just write: GETINDEX(a, i) SETINDEX(a, i, x) instead of a[i] or a[i]=x. Except these need special headers to be dragged in, and everyone would be using their own incompatible macros; try mixing code from different sources. > You need very good reasons for > adding non-portable extensions. Such a set of macros as you propose would also be non-portable unless you included custom headers. And then you mix code that needs BIT(a,10,1) with code that needs BIT(a,1,10). You don't however seem to mind using GNU C extensions!
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-07-10 13:28 +0200 |
| Message-ID | <scc085$6h2$1@dont-email.me> |
| In reply to | #161781 |
On 09/07/2021 14:44, Bart wrote: > On 09/07/2021 09:27, David Brown wrote: >> On 09/07/2021 00:45, Robert Finch wrote: >>> On Thursday, July 8, 2021 at 1:47:12 PM UTC-4, Kaz Kylheku wrote: >>>> A macro can do this: >>>> >>>> a = BIT(b,10,1); >>>> >>>> and works everywhere. What you need is a typeof extension to make it >>>> work with different integer types while retaining efficiency, otherwise >>>> you're looking at making it assume 64 bit, or saddling it with a type >>>> name argument. >>> >>> One should not have to write macros for commonly used language elements. >> >> Your extension is not commonly used, because it only exists in your >> tool. People who need to do a lot of bit slicing and don't like masking >> and shifting (or struct bit-fields) should not have trouble defining: >> >> #define BIT(x, top, bottom) \ >> (((x) >> (bottom)) & ((1llu << ((top) - (bottom) + 1)) - 1)) >> >> Yes, the parenthesis you need for macros are ugly, but you only need to >> get it right once, and now you can read your bit-fields. >> >> Having said that, it is not at all unreasonable for an embedded compiler >> to ship with extra headers, which would be an excellent place to put >> macros like this for user convenience. It would be simpler and clearer >> to C programmers who are not used to your extensions. This is the >> technique used by other embedded compilers. >> >> I'm not saying the extension is not useful, or bad in itself - but I >> dislike adding extensions when it is perfectly possible to get the same >> results without changing the language. > > Then there would have been no need for the [] indexing syntax either. > You'd just write: > > GETINDEX(a, i) > SETINDEX(a, i, x) > > instead of a[i] or a[i]=x. Except these need special headers to be > dragged in, and everyone would be using their own incompatible macros; > try mixing code from different sources. In a programming language, you want convenient syntax for things you do a lot, and you can happily have inconvenient syntax for things you only need to do occasionally. (This works the other way too - you pick a language that has convenient syntax for the things you do often. Or at least, that's what sensible programmers do. Some people prefer to pick a language they don't like and complain instead.) Accessing bit-fields like this is very rare - even in embedded programming, it is not something you do so much that existing C syntax is a problem. Accessing arrays, however, is massively useful. > >> You need very good reasons for >> adding non-portable extensions. > > Such a set of macros as you propose would also be non-portable unless > you included custom headers. And then you mix code that needs > BIT(a,10,1) with code that needs BIT(a,1,10). Yes, but the great thing about headers with simple macros is that they are extremely portable. > > You don't however seem to mind using GNU C extensions! No, I don't - but I generally don't need my code to be portable beyond gcc and occasionally a few older embedded compilers. There are two C and C++ toolchains that totally dominate - MSVC on Windows, and gcc on everything else. The next most popular toolchains are clang then probably icc, both of which support a fair number of gcc extensions. So a gcc extension is likely to be portable to perhaps 90% of all non-Windows C or C++ development work. That's more than good enough for my needs. An extension in /your/ tool, or Robert Finch's tool, is portable to perhaps 0.0000000001% of C or C++ development work. That is rather different. Of course if you are writing code that only ever needs to run on these home-made tools, then use your extensions - you made them, so use them.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2021-07-10 13:04 +0100 |
| Message-ID | <scc2cs$orb$1@dont-email.me> |
| In reply to | #161815 |
On 10/07/2021 12:28, David Brown wrote: > On 09/07/2021 14:44, Bart wrote: >> Then there would have been no need for the [] indexing syntax either. >> You'd just write: >> >> GETINDEX(a, i) >> SETINDEX(a, i, x) >> >> instead of a[i] or a[i]=x. Except these need special headers to be >> dragged in, and everyone would be using their own incompatible macros; >> try mixing code from different sources. > > In a programming language, you want convenient syntax for things you do > a lot, and you can happily have inconvenient syntax for things you only > need to do occasionally. (This works the other way too - you pick a > language that has convenient syntax for the things you do often. Or at > least, that's what sensible programmers do. Some people prefer to pick > a language they don't like and complain instead.) > > Accessing bit-fields like this is very rare - even in embedded > programming, it is not something you do so much that existing C syntax > is a problem. Accessing arrays, however, is massively useful. It's probably rare because the language doesn't support them! If available, they would be used a lot more. (As you've said, the macro to set the value of an arbitrary bitfield is not trivial.) C does have bitfield indexing, but only for named fields in structs and with poor control over layout. Having it available for any integer value would be convenient. I don't use bit/bitfield indexing that much, but the underlying mechanisms needed for that are used to implement my own, better-controlled version of C's struct bitfields. And used to allow things like A.msb (as both lvalue and rvalue), and A.even/A.odd (rvalue only). > >> >>> You need very good reasons for >>> adding non-portable extensions. >> >> Such a set of macros as you propose would also be non-portable unless >> you included custom headers. And then you mix code that needs >> BIT(a,10,1) with code that needs BIT(a,1,10). > > Yes, but the great thing about headers with simple macros is that they > are extremely portable. Nothing is more portable than what is built-in to a language or to a standard library. I keep coming across macros for min and max, or MIN and MAX, or ones to extract an array length without having to do that dance with sizeof this over sizeof that. All candidates for standardisation. >> >> You don't however seem to mind using GNU C extensions! > > No, I don't - but I generally don't need my code to be portable beyond > gcc and occasionally a few older embedded compilers. > > There are two C and C++ toolchains that totally dominate - MSVC on > Windows, and gcc on everything else. The next most popular toolchains > are clang then probably icc, both of which support a fair number of gcc > extensions. > > So a gcc extension is likely to be portable to perhaps 90% of all > non-Windows C or C++ development work. That's more than good enough for > my needs. > > An extension in /your/ tool, or Robert Finch's tool, is portable to > perhaps 0.0000000001% of C or C++ development work. That is rather > different. The ideas would be portable to 99% of C implementations if they prove viable and useful (remember my 'strinclude' feature). Where do you think most gcc extensions came from?
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-07-10 15:39 +0200 |
| Message-ID | <scc7tq$cr9$1@dont-email.me> |
| In reply to | #161816 |
On 10/07/2021 14:04, Bart wrote: > On 10/07/2021 12:28, David Brown wrote: >> On 09/07/2021 14:44, Bart wrote: > >>> Then there would have been no need for the [] indexing syntax either. >>> You'd just write: >>> >>> GETINDEX(a, i) >>> SETINDEX(a, i, x) >>> >>> instead of a[i] or a[i]=x. Except these need special headers to be >>> dragged in, and everyone would be using their own incompatible macros; >>> try mixing code from different sources. >> >> In a programming language, you want convenient syntax for things you do >> a lot, and you can happily have inconvenient syntax for things you only >> need to do occasionally. (This works the other way too - you pick a >> language that has convenient syntax for the things you do often. Or at >> least, that's what sensible programmers do. Some people prefer to pick >> a language they don't like and complain instead.) >> >> Accessing bit-fields like this is very rare - even in embedded >> programming, it is not something you do so much that existing C syntax >> is a problem. Accessing arrays, however, is massively useful. > > > It's probably rare because the language doesn't support them! No, it is because bit-fields like this are not commonly useful. > If > available, they would be used a lot more. (As you've said, the macro to > set the value of an arbitrary bitfield is not trivial.) > > C does have bitfield indexing, but only for named fields in structs and > with poor control over layout. Having it available for any integer value > would be convenient. I really don't see that. And I do the kind of work where it would be most likely to be useful. (I would have liked clearer specifications of bit-field layout in C.) > > I don't use bit/bitfield indexing that much, but the underlying > mechanisms needed for that are used to implement my own, > better-controlled version of C's struct bitfields. > > And used to allow things like A.msb (as both lvalue and rvalue), and > A.even/A.odd (rvalue only). > Why? Can you give examples where these would be used often enough to deserve their own special syntax, and where that syntax would be clearer than "x & 1", "x |= 1", "x % 2", etc.? (I'll accept that masking off a bit - "x &= ~1u" - is not great.) >> >>> >>>> You need very good reasons for >>>> adding non-portable extensions. >>> >>> Such a set of macros as you propose would also be non-portable unless >>> you included custom headers. And then you mix code that needs >>> BIT(a,10,1) with code that needs BIT(a,1,10). >> >> Yes, but the great thing about headers with simple macros is that they >> are extremely portable. > > Nothing is more portable than what is built-in to a language or to a > standard library. > > I keep coming across macros for min and max, or MIN and MAX, or ones to > extract an array length without having to do that dance with sizeof this > over sizeof that. All candidates for standardisation. > These could certainly be standardised in some way, I agree. C++ has done so. >>> >>> You don't however seem to mind using GNU C extensions! >> >> No, I don't - but I generally don't need my code to be portable beyond >> gcc and occasionally a few older embedded compilers. >> >> There are two C and C++ toolchains that totally dominate - MSVC on >> Windows, and gcc on everything else. The next most popular toolchains >> are clang then probably icc, both of which support a fair number of gcc >> extensions. >> >> So a gcc extension is likely to be portable to perhaps 90% of all >> non-Windows C or C++ development work. That's more than good enough for >> my needs. >> >> An extension in /your/ tool, or Robert Finch's tool, is portable to >> perhaps 0.0000000001% of C or C++ development work. That is rather >> different. > > The ideas would be portable to 99% of C implementations if they prove > viable and useful (remember my 'strinclude' feature). Where do you think > most gcc extensions came from? It's absolutely fine to try out new ideas for extensions in a compiler, and if they look good, suggest to other compilers that it would be a useful extension there. If some idea really is useful, it's quite likely that many people will think of basically the same think and there's a chance it will get into the language sooner or later.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2021-07-10 15:08 +0100 |
| Message-ID | <scc9k8$rth$1@dont-email.me> |
| In reply to | #161819 |
On 10/07/2021 14:39, David Brown wrote: > On 10/07/2021 14:04, Bart wrote: >> It's probably rare because the language doesn't support them! > > No, it is because bit-fields like this are not commonly useful. > >> If >> available, they would be used a lot more. (As you've said, the macro to >> set the value of an arbitrary bitfield is not trivial.) >> >> C does have bitfield indexing, but only for named fields in structs and >> with poor control over layout. Having it available for any integer value >> would be convenient. > > I really don't see that. And I do the kind of work where it would be > most likely to be useful. Maybe you're too used with dealing with bit manipulation using code like your examples below. I guess you don't use macros like GETBIT, as that would mean you do find it useful. >> And used to allow things like A.msb (as both lvalue and rvalue), and >> A.even/A.odd (rvalue only). >> > > Why? Can you give examples where these would be used often enough to > deserve their own special syntax, and where that syntax would be clearer > than "x & 1", "x |= 1", "x % 2", etc.? > > (I'll accept that masking off a bit - "x &= ~1u" - is not great.) OK, I'll try to translate your examples (into my syntax not CC64 if that's the OP's compiler): x & 1 x.[0] (or x.lsbit) extract least sig bit x |= 1 x.[0] := 1 Set ls bit to 1 x % 2 x.[0] (When x is positive or unsigned) x &= ~1u x.[0] := 0 Set ls bit to 0 I had to think carefully about these, then double check. Even if correct, these may not directly reflect your intentions. Whereas those bit operations are exactly that. Somebody looking at x & k would not be able to tell if k refered to a single bit, a contiguous bit, or is some arbitrary value that cannot be expressed as a bit-index op. (Not without making it more elaborate.) Somebody looking at x.[k] could. Dedicated ops just make this stuff incredibly easy, with less chance of error. Notice that in C, all those bit-0 manipulations used either 1 or 2
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-07-10 17:34 +0200 |
| Message-ID | <sccelb$u6s$1@dont-email.me> |
| In reply to | #161820 |
On 10/07/2021 16:08, Bart wrote: > On 10/07/2021 14:39, David Brown wrote: >> On 10/07/2021 14:04, Bart wrote: > >>> It's probably rare because the language doesn't support them! >> >> No, it is because bit-fields like this are not commonly useful. >> >>> If >>> available, they would be used a lot more. (As you've said, the macro to >>> set the value of an arbitrary bitfield is not trivial.) >>> >>> C does have bitfield indexing, but only for named fields in structs and >>> with poor control over layout. Having it available for any integer value >>> would be convenient. >> >> I really don't see that. And I do the kind of work where it would be >> most likely to be useful. > > Maybe you're too used with dealing with bit manipulation using code like > your examples below. > > I guess you don't use macros like GETBIT, as that would mean you do find > it useful. I don't use macros like GETBIT, no. Most often, I use the method defined by the microcontroller manufacturer that provided the header file for accessing the hardware registers for the microcontroller. Sometimes that is bit-field structs, but most often it is with structures, constants and macros so that you write something on the lines of : timer1.controlreg |= TIMER_CONTROLREG_CLOCKSOURCE(4); for setting the "clocksource" field of timer 1's control register to 4. And if it is something I am using more than once or twice, it is going to be wrapped in a function anyway. A compiler extension to let me access bits of a variable via array-like syntax would be of precisely /zero/ use to me here. > >>> And used to allow things like A.msb (as both lvalue and rvalue), and >>> A.even/A.odd (rvalue only). >>> >> >> Why? Can you give examples where these would be used often enough to >> deserve their own special syntax, and where that syntax would be clearer >> than "x & 1", "x |= 1", "x % 2", etc.? >> >> (I'll accept that masking off a bit - "x &= ~1u" - is not great.) > > OK, I'll try to translate your examples (into my syntax not CC64 if > that's the OP's compiler): > > x & 1 x.[0] (or x.lsbit) extract least sig bit > > x |= 1 x.[0] := 1 Set ls bit to 1 > > x % 2 x.[0] (When x is positive or unsigned) > > x &= ~1u x.[0] := 0 Set ls bit to 0 > > I had to think carefully about these, then double check. > Your syntax is clear enough - why would you have to think hard about it? Or are you just saying you are not very familiar with C? (I don't think there is anything bad about your syntax, I just don't see it as a particularly useful feature or one worth adding to C.) > Even if correct, these may not directly reflect your intentions. Whereas > those bit operations are exactly that. > > Somebody looking at x & k would not be able to tell if k refered to a > single bit, a contiguous bit, or is some arbitrary value that cannot be > expressed as a bit-index op. (Not without making it more elaborate.) > > Somebody looking at x.[k] could. > > Dedicated ops just make this stuff incredibly easy, with less chance of > error. Notice that in C, all those bit-0 manipulations used either 1 or 2 > They are easy enough in C. And since they are rarely needed in practice (you haven't given examples of real-world use-cases), "easy enough" is all you need. "Incredibly easy" doesn't add much - you would be better off spending the effort elsewhere.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2021-07-10 17:47 +0100 |
| Message-ID | <sccivt$s3k$1@dont-email.me> |
| In reply to | #161828 |
On 10/07/2021 16:34, David Brown wrote:
> On 10/07/2021 16:08, Bart wrote:
>> I guess you don't use macros like GETBIT, as that would mean you do find
>> it useful.
>
> I don't use macros like GETBIT, no. Most often, I use the method
> defined by the microcontroller manufacturer that provided the header
> file for accessing the hardware registers for the microcontroller.
> Sometimes that is bit-field structs, but most often it is with
> structures, constants and macros so that you write something on the
> lines of :
>
> timer1.controlreg |= TIMER_CONTROLREG_CLOCKSOURCE(4);
>
> for setting the "clocksource" field of timer 1's control register to 4.
>
> And if it is something I am using more than once or twice, it is going
> to be wrapped in a function anyway.
>
> A compiler extension to let me access bits of a variable via array-like
> syntax would be of precisely /zero/ use to me here.
It would be of use to the manufacturer who provides the header file.
But I'm not sure your example is correct; if clocksource is a bitfield
of timer.controlreg, it would only set it to 4 if it's currently zero
(or already 4).
What does TIMER_CONTROLREG_CLOCKSOURCE do, shift the 4 up to be in the
right place, making sure other bits are zero? To /replace/ the field is
a more complex operation.
If clocksource is a 4-bit field, say occupying bits 8..11, bitfield ops
would allow:
timer.controlreg.[8..11] := 4
timer.controlreg[11:8] = 4 // with CC64
Although you would define constants or macros for these so that you'd
write .clocksource or .[clocksource].
>> I had to think carefully about these, then double check.
>>
>
> Your syntax is clear enough - why would you have to think hard about it?
> Or are you just saying you are not very familiar with C?
I had to decode the C to see exactly what you were attempting
>> Dedicated ops just make this stuff incredibly easy, with less chance of
>> error. Notice that in C, all those bit-0 manipulations used either 1 or 2
>>
>
> They are easy enough in C. And since they are rarely needed in practice
> (you haven't given examples of real-world use-cases), "easy enough" is
> all you need. "Incredibly easy" doesn't add much - you would be better
> off spending the effort elsewhere.
Every real-world example could be done with logical operations or using
a different approach entirely; it's always very easy in a 1-line example
on a forum where people can find these solutions at leisure.
(For that matter, all logical operations could probably be replaced by
arihtmetic ones too.)
It's about not spending a few seconds having to stop think about this
when writing or reading, which is a distraction from what you really
want to do, which is to get or set some bits without worrying about the
mechanisms for doing so, or having to instruct the compiler how to.
But there's one example which was a debug print of an int that
represented a colour value:
println "rgb=",col.[0..7],col.[8..15],col.[16..23]
Another from some old code, which here defines bits or bitfields which
are accessed using A.[fnfont] and so on:
macro fnfont = 0..5
macro fnsize = 6..12
macro fnbold = 13
macro fnitalic = 14
macro fnunderline = 15
macro fnattrib = fnbold..fnunderline
macro fnaspect = 16..18
macro fncolour = 19..24
macro fnbgnd = 25..30
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2021-07-11 00:57 -0700 |
| Message-ID | <861r858eqz.fsf@linuxsc.com> |
| In reply to | #161759 |
Kaz Kylheku <563-365-8930@kylheku.com> writes: > On 2021-07-08, Robert Finch <robfi680@gmail.com> wrote: > >>> You wrote that you "have been working on a C/C++ like compiler" - do you >>> mean you have been /using/ such a compiler, or you have been /writing/ >>> such a compiler? >> >> I have been using it for simple demos, actually running the compiled >> code sometime. It has been revamped for several different custom >> processors, but is still a work in progress. >> >>> As I mentioned earlier, I think a "naked switch" like this is a terrible >>> idea. It is not something I have seen on other compilers, and I've used >>> quite a large number over the years for far smaller and slower devices >>> than you are describing here. >> >> It is a bad idea in terms of allowing program crashes. But then >> there are naked functions. >> >> CC64 supports a number of ?features? not found in standard C. But I >> call it a ?C? like compiler because it can compile most C code >> without changes. I used it to compile the standard C library. >> Stills lots of bugs in the compiler though. >> >> One feature I like is the ability to manipulate bit slices. >> >> int a, b; >> >> a = b[10:1]; >> >> Sets a equal to bits 1 to 10 of b. A bit slice can be distinguished >> from an array index by the colon. Compiles painlessly directly to >> field manipulation instructions and gets rid of code like: a = (b >> >> 1) & 0x3ff; > > A macro can do this: > > a = BIT(b,10,1); > > and works everywhere. What you need is a typeof extension to make it > work with different integer types while retaining efficiency, otherwise > you're looking at making it assume 64 bit, or saddling it with a type > name argument. [... and later _Generic is mentioned.] No typeof is needed, nor _Generic, nor type name argument, nor forcing a width of 64 bits, to define a macro that produces an "and" of the appropriate size with a compile-time constant (as evidenced by both gcc and clang with -O0). Just straight C90. (I'll try to post a followup in a day or two, if necessary, to show how. But I expect someone here will get it before then.)
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2021-07-16 03:51 -0700 |
| Message-ID | <868s267cqn.fsf@linuxsc.com> |
| In reply to | #161869 |
Tim Rentsch <tr.17687@z991.linuxsc.com> writes: > Kaz Kylheku <563-365-8930@kylheku.com> writes: > >> On 2021-07-08, Robert Finch <robfi680@gmail.com> wrote: >> >>>> You wrote that you "have been working on a C/C++ like compiler" - do you >>>> mean you have been /using/ such a compiler, or you have been /writing/ >>>> such a compiler? >>> >>> I have been using it for simple demos, actually running the compiled >>> code sometime. It has been revamped for several different custom >>> processors, but is still a work in progress. >>> >>>> As I mentioned earlier, I think a "naked switch" like this is a terrible >>>> idea. It is not something I have seen on other compilers, and I've used >>>> quite a large number over the years for far smaller and slower devices >>>> than you are describing here. >>> >>> It is a bad idea in terms of allowing program crashes. But then >>> there are naked functions. >>> >>> CC64 supports a number of ?features? not found in standard C. But I >>> call it a ?C? like compiler because it can compile most C code >>> without changes. I used it to compile the standard C library. >>> Stills lots of bugs in the compiler though. >>> >>> One feature I like is the ability to manipulate bit slices. >>> >>> int a, b; >>> >>> a = b[10:1]; >>> >>> Sets a equal to bits 1 to 10 of b. A bit slice can be distinguished >>> from an array index by the colon. Compiles painlessly directly to >>> field manipulation instructions and gets rid of code like: a = (b >> >>> 1) & 0x3ff; >> >> A macro can do this: >> >> a = BIT(b,10,1); >> >> and works everywhere. What you need is a typeof extension to make it >> work with different integer types while retaining efficiency, otherwise >> you're looking at making it assume 64 bit, or saddling it with a type >> name argument. [... and later _Generic is mentioned.] > > No typeof is needed, nor _Generic, nor type name argument, nor > forcing a width of 64 bits, to define a macro that produces an > "and" of the appropriate size with a compile-time constant (as > evidenced by both gcc and clang with -O0). Just straight C90. > > (I'll try to post a followup in a day or two, if necessary, to > show how. But I expect someone here will get it before then.) To extract a "field" from expression 'e' of width 'w' at position 'p' #define FIELD(e,w,p) ( (e)>>(p) & ( ( (0?(e):1) << (w)-1 ) -1) *2 +1 ) The idiom (0?(e):1) produces the value 1 in a type wide enough to mask a field in the expression of 'e' (assuming the field does not include the sign bit of a signed integer type).
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2021-07-08 11:40 -0700 |
| Message-ID | <87y2ag7ip9.fsf@nosuchdomain.example.com> |
| In reply to | #161751 |
Robert Finch <robfi680@gmail.com> writes:
> On Thursday, July 8, 2021 at 6:25:26 AM UTC-4, Malcolm McLean wrote:
>> On Thursday, 8 July 2021 at 09:00:40 UTC+1, Keith Thompson wrote:
>> > Robert Finch <robf...@gmail.com> writes:
>> > > I have been working on a C/C++ like compiler. One feature supported in
>> > > the compiler is naked switches. A naked switch omits the range
>> > > checking code that is normally associated with the switch
>> > > statement. Omitting this code can improve performance at the risk of a
>> > > crash if invalid cases are processed. I am wondering if there is a
>> > > similar option in other C compilers? Or would this just be an
>> > > automatic optimization at high levels?
>> > What range checking code are you referring to? Can you give an example
>> > in C that demonstrates the change in behavior? How does a default:
>> >
>> Normal switch
>>
>> foo(int x)
>> {
>> switch(x)
>> {
>> case 1: printf("one\n"); break;
>> case 2: printf("two\n"); break;
>> case 3:: printf("three\n"); break;
>> case 4: printf("four\n"): break;
>> default: printf("x is in error\n"); break;
>> }
>> }
>>
>> That will compile to something like the following
>> if(x < 1 || x > 4) x -= 5;
>> x -= 1;
>> goto jumptable[x]
That's a normal switch, not a naked one, and the if/goto code is not
equivalent to the switch. If x is 42, the switch statement will print
"x is in error"; the if/goto code (assuming "goto jumptable[x]" has the
obvious meaning) has undefined behavior. Or did you intend this to
be a naked switch?
>> Namke switch
>>
>> foo(int x)
>> {
>> nakedswitch(x)
>> {
>> case 1: printf("one\n"); break;
>> case 2: printf("two\n"); break;
>> case 3:: printf("three\n"); break;
>> case 4: printf("four\n"): break;
>> }
>> }
>>
>> would compile to the following
>> /* jumptable[0] = NULL; */
>> goto jumptable[x];
>>
>> so x is unchecked. If it is out of range, the program crashes.
>
> That is basically how it is working. There is still a default
> statement for unimplemented values between the min and max. The table
> entry may as well point somewhere useful. There were two goals with
> this, a) a performance optimization and b) code size optimization. I
> am dealing with small roms in an FPGA so bytes count. The processor is
> also rather slow <40MHz.
So here's my understanding of how nakedswitch might be defined:
If there is no default: label, then it acts like a normal switch *except
that* if the value of x is less than the smallest case value or greater
than the largest case value, the behavior is undefined. Is that the intent?
If there is a default: value, then ... what?
And both examples use contiguous ranges of values. How would this
behave?
int x = 15;
nakedswitch(x) {
case 10: puts("ten"); break;
case 20: puts("twenty"); break;
}
There are no "range checks" in the defined behavior of a C switch
statement, and no requirement that they be implemented using a jump
table.
(What I'm looking for is a definition of the *behavior* of a
nakedswitch, including the exact situations where the behavior is
undefined.)
Many years ago, I used a Pascal compiler that always compiled case
statements to a jump table. When I wrote a case statement with cases 1,
10, 100, 1000, 10000, it crashed the compiler. gcc, for example, will
generate the equivalent of either a jump table or an if/else chain
depending on the values.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-07-09 10:38 +0200 |
| Message-ID | <sc91uq$l99$1@dont-email.me> |
| In reply to | #161762 |
On 08/07/2021 20:40, Keith Thompson wrote:
> Many years ago, I used a Pascal compiler that always compiled case
> statements to a jump table. When I wrote a case statement with cases 1,
> 10, 100, 1000, 10000, it crashed the compiler. gcc, for example, will
> generate the equivalent of either a jump table or an if/else chain
> depending on the values.
>
gcc has a lot more options than that. For example :
int floo(int x) {
if ((x < 1) || (x > 4)) __builtin_unreachable();
switch (x) {
case 1 : return 100;
case 2 : return 200;
case 3 : return 300;
case 4 : return 400;
}
return 0;
}
With this, the assembly generated by gcc (on x86) is equivalent to :
int floo(int x) {
int y = 100;
if (x < 2) return y;
return x * y;
}
(On other targets where multiplication is cheaper than the conditional,
it may omit that check.)
And with a sparse switch, the if/else pattern generated is a binary tree
rather than a linear chain.
There are lots of options for implementing switches.
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <563-365-8930@kylheku.com> |
|---|---|
| Date | 2021-07-08 17:33 +0000 |
| Message-ID | <20210708101340.323@kylheku.com> |
| In reply to | #161725 |
On 2021-07-07, Robert Finch <robfi680@gmail.com> wrote:
> I have been working on a C/C++ like compiler. One feature supported in
> the compiler is naked switches. A naked switch omits the range
> checking code that is normally associated with the switch statement.
> Omitting this code can improve performance at the risk of a crash if
> invalid cases are processed. I am wondering if there is a similar
> option in other C compilers? Or would this just be an automatic
> optimization at high levels?
GNU C has the feature that labels can be treated as data; they
can be stored in variables/objects and used to perform a goto.
Thus GNU C has two computed-goto mechanisms: the regular switch
which branches to a fixed case label via a computed value,
and the literal computed goto, which branchews to a label pointer
retrieved from an object.
GNU C code can construct an array, which is populated with goto labels,
and then use it as a completely usafe, unchecked jump table.
It looks something like:
void *table[] = { &&L1, &&L2, &&L3, ... };
goto *table[x];
L1:
// code
goto somewhere;
L2;
// code
goto somewhere;
This not only ensures that there is no range check, but ensures that the
run-time representation of the control flow is a jump table in the first
place, as a matter of the program's expressed abstractc semantics rather
than optimization.
You could dress this up with some macros:
SWITCH(x, table, ENUM_FOO, ENUM_BAR, ENUM_XYZZY)
CASE(ENUM_FOO) statement;
CASE(ENUM_BAR) statement;
CASE(ENUM_XYZZY) { compound statement }
ENDSWITCH;
How to implement? Use some convoluted C99+ preprocessor tricks, which
I'm 95% certain are possible, to spin the first macro into the output:
void *table[] = { &&L_ENUM_FOO, &&L_ENUM_BAR, &&L_ENUM_XYZZY };
goto *table[x];
The CASE macros are easy:
#define CASE(LAB) if (0) L_ ## LAB:
The if (0) ensures that control falls through cases that are entered
from above without a goto. Thus when each case statement terminates, it
will fall through to the bottom, skipping all subsequent cases.
The ENDSWITCH macro does nothing; but it allows us to retarget
the macros to an ordinary switch statement if we are not on GCC/clang:
#define SWITCH(EXPR, TABLE, LAB ...) switch (x) {
#define CASE(LAB) if (0) case LAB:
#define ENDSWITCH }
Nothing tested in this article. :)
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2021-07-08 17:47 +0000 |
| Message-ID | <QSGFI.7387$qk6.4293@fx36.iad> |
| In reply to | #161757 |
Kaz Kylheku <563-365-8930@kylheku.com> writes: >On 2021-07-07, Robert Finch <robfi680@gmail.com> wrote: >> I have been working on a C/C++ like compiler. One feature supported in >> the compiler is naked switches. A naked switch omits the range >> checking code that is normally associated with the switch statement. >> Omitting this code can improve performance at the risk of a crash if >> invalid cases are processed. I am wondering if there is a similar >> option in other C compilers? Or would this just be an automatic >> optimization at high levels? > >GNU C has the feature that labels can be treated as data; they >can be stored in variables/objects and used to perform a goto. GCC generally generates optimal code sequences for switch statements; from simple sequenced branches for small case counts to jump tables for larger case counts.
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <563-365-8930@kylheku.com> |
|---|---|
| Date | 2021-07-08 17:58 +0000 |
| Message-ID | <20210708105401.685@kylheku.com> |
| In reply to | #161760 |
On 2021-07-08, Scott Lurndal <scott@slp53.sl.home> wrote: > Kaz Kylheku <563-365-8930@kylheku.com> writes: >>On 2021-07-07, Robert Finch <robfi680@gmail.com> wrote: >>> I have been working on a C/C++ like compiler. One feature supported in >>> the compiler is naked switches. A naked switch omits the range >>> checking code that is normally associated with the switch statement. >>> Omitting this code can improve performance at the risk of a crash if >>> invalid cases are processed. I am wondering if there is a similar >>> option in other C compilers? Or would this just be an automatic >>> optimization at high levels? >> >>GNU C has the feature that labels can be treated as data; they >>can be stored in variables/objects and used to perform a goto. > > GCC generally generates optimal code sequences for switch > statements; from simple sequenced branches for small case > counts to jump tables for larger case counts. Elsewhere in the thread, I was not able to coax GCC into eliminating the range test and branch prior to the table switch, even if the default: case of the switch was __builtin_unreachable(). Since two instructions can be removed form the code, it must not be optimal. -- TXR Programming Language: http://nongnu.org/txr Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2021-07-08 19:13 +0000 |
| Message-ID | <Q7IFI.2749$Ei1.978@fx07.iad> |
| In reply to | #161761 |
Kaz Kylheku <563-365-8930@kylheku.com> writes: >On 2021-07-08, Scott Lurndal <scott@slp53.sl.home> wrote: >> Kaz Kylheku <563-365-8930@kylheku.com> writes: >>>On 2021-07-07, Robert Finch <robfi680@gmail.com> wrote: >>>> I have been working on a C/C++ like compiler. One feature supported in >>>> the compiler is naked switches. A naked switch omits the range >>>> checking code that is normally associated with the switch statement. >>>> Omitting this code can improve performance at the risk of a crash if >>>> invalid cases are processed. I am wondering if there is a similar >>>> option in other C compilers? Or would this just be an automatic >>>> optimization at high levels? >>> >>>GNU C has the feature that labels can be treated as data; they >>>can be stored in variables/objects and used to perform a goto. >> >> GCC generally generates optimal code sequences for switch >> statements; from simple sequenced branches for small case >> counts to jump tables for larger case counts. > >Elsewhere in the thread, I was not able to coax GCC into eliminating the >range test and branch prior to the table switch, even if the default: >case of the switch was __builtin_unreachable(). > >Since two instructions can be removed form the code, it must not be >optimal. Do the instructions actually affect performance? Unlikely, given modern branch predictors. And vectoring through a bogus entry in a jump table should be avoided.
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <563-365-8930@kylheku.com> |
|---|---|
| Date | 2021-07-09 02:30 +0000 |
| Message-ID | <20210708133106.869@kylheku.com> |
| In reply to | #161763 |
On 2021-07-08, Scott Lurndal <scott@slp53.sl.home> wrote: > Kaz Kylheku <563-365-8930@kylheku.com> writes: >>On 2021-07-08, Scott Lurndal <scott@slp53.sl.home> wrote: >>> Kaz Kylheku <563-365-8930@kylheku.com> writes: >>>>On 2021-07-07, Robert Finch <robfi680@gmail.com> wrote: >>>>> I have been working on a C/C++ like compiler. One feature supported in >>>>> the compiler is naked switches. A naked switch omits the range >>>>> checking code that is normally associated with the switch statement. >>>>> Omitting this code can improve performance at the risk of a crash if >>>>> invalid cases are processed. I am wondering if there is a similar >>>>> option in other C compilers? Or would this just be an automatic >>>>> optimization at high levels? >>>> >>>>GNU C has the feature that labels can be treated as data; they >>>>can be stored in variables/objects and used to perform a goto. >>> >>> GCC generally generates optimal code sequences for switch >>> statements; from simple sequenced branches for small case >>> counts to jump tables for larger case counts. >> >>Elsewhere in the thread, I was not able to coax GCC into eliminating the >>range test and branch prior to the table switch, even if the default: >>case of the switch was __builtin_unreachable(). >> >>Since two instructions can be removed form the code, it must not be >>optimal. > > Do the instructions actually affect performance? Unlikely, given > modern branch predictors. If the branch instruction is deleted, then it doesn't require branch prediction. Branch prediction isn't free; it requires a cache of information. Any time you put something in it, something else gets bumped. Not emitting the compare and branch instruction also means that the code sequence is two instructions shorter. That has to save something. Size matters. Two instructions less means room for two more instructions from somewhere else to fit into the instruction cache. -- TXR Programming Language: http://nongnu.org/txr Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-07-09 10:41 +0200 |
| Message-ID | <sc9239$l99$2@dont-email.me> |
| In reply to | #161761 |
On 08/07/2021 19:58, Kaz Kylheku wrote: > On 2021-07-08, Scott Lurndal <scott@slp53.sl.home> wrote: >> Kaz Kylheku <563-365-8930@kylheku.com> writes: >>> On 2021-07-07, Robert Finch <robfi680@gmail.com> wrote: >>>> I have been working on a C/C++ like compiler. One feature supported in >>>> the compiler is naked switches. A naked switch omits the range >>>> checking code that is normally associated with the switch statement. >>>> Omitting this code can improve performance at the risk of a crash if >>>> invalid cases are processed. I am wondering if there is a similar >>>> option in other C compilers? Or would this just be an automatic >>>> optimization at high levels? >>> >>> GNU C has the feature that labels can be treated as data; they >>> can be stored in variables/objects and used to perform a goto. >> >> GCC generally generates optimal code sequences for switch >> statements; from simple sequenced branches for small case >> counts to jump tables for larger case counts. > > Elsewhere in the thread, I was not able to coax GCC into eliminating the > range test and branch prior to the table switch, even if the default: > case of the switch was __builtin_unreachable(). > > Since two instructions can be removed form the code, it must not be > optimal. > Did you try my suggestion of using a newer gcc? You can test it out on <https://godbolt.org>. gcc isn't perfect, and each new version adds new tweaks and optimisations (and new features, and the occasional bug, regression, etc.).
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2021-09-30 18:04 +0200 |
| Message-ID | <sj4n6b$f7i$1@dont-email.me> |
| In reply to | #161725 |
Am 08.07.2021 um 01:39 schrieb Robert Finch:
> I have been working on a C/C++ like compiler. One feature supported in the compiler is naked switches. A naked switch omits the range checking code that is normally associated with the switch statement. Omitting this code can improve performance at the risk of a crash if invalid cases are processed. I am wondering if there is a similar option in other C compilers? Or would this just be an automatic optimization at high levels?
>
> Normal Switch:
>
> ; switch(x) {
> ldo $t0,64[$fp]
> sge $t1,$t0,#1 ; x varies between 1 and 12
> sle $t2,$t0,#12
> and $t1,$t1,$t2
> beq $t1,TestSwitch_89
> sub $t0,$t0,#1
> sll $t0,$t0,#4
> ldo $t0,TestSwitch_116[$t0]
> jmp $t0
>
> Naked Switch
> ; switch(x; naked) {
> ldo $t0,64[$fp]
> sub $t0,$t0,#1
> sll $t0,$t0,#4
> ldo $t0,TestSwitch_144[$t0]
> jmp $t0
>
Don't make such strange C-extensions.
Help the optimizer with sth. like __assume in MSVC++.
[toc] | [prev] | [standalone]
Page 3 of 3 — ← Prev page 1 2 [3]
Back to top | Article view | comp.lang.c
csiph-web