🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.intel
Article #1937

Re: PLM vs. C for 80286/80386

#1937
From: Tom Neff
Date: Fri, 09 Jun 1989 00:37
69 lines
3278 bytes
[Talking about jump tables versus elseif's for dense 'case' constructs.]

In article <1782@auspex.auspex.com> guy@auspex.auspex.com (Guy Harris) writes:
>Try a few more arms; if you make it up to, say, 32 arms, and it *still*
>generates an if/then/elseif/then... chain, the compiler is probably
>being dumb (but check the cycle counts anyway, just for fun...).  If
>there is an inflection point, check the cycle counts, etc. to see
>whether an if/then/elseif/then... chain makes sense for a number of
>arms below the inflection point.  If so, perhaps the PL/M compiler is
>the wrong one....

[Side note: in a separate posting I confirm that iC-x86 does change
to a jump table at the "inflection point" of 6 or more cases.  I had
tried 3 and 5 before retesting and just plain missed it.]

I would make the claim that in critical realtime code it's more
important to have *consistent* code generation for things like 4- and
5- and 6- case state machines than it is to try and shave the extra
cycle by using a completely different algorithm below (undocumented) N
number of cases. That's the kind of thing that riseth up to smite
the harried sysprog at JUST the wrong time, like when the boss screaming
at you from an overseas conference room where Something Went Wrong. :-)

The thing is, if you want an elseif construct you can always CODE ONE
YOURSELF in any language.  The whole point of DO CASE (PL/M) or switch
(C) for dense case lists should be to use something different, i.e.
a jump table.   PL/M does this perforce because its DO CASE is like
'switch' without 'case' - each simple or compound statement within
the DO CASE scope is assumed to handle the next integer value of the
control expression starting at 0 -- thus:

	DO CASE state;

		;		/*  case 0 - shouldn't happen  */


		DO;		/*  case 1 - do something  */
			masterflags.busy = TRUE;
			val = get$something(x, y, @status);
			CALL OUTWORD(that$port, val);
			state = 2;
			END;

		DO;		/*  case 2 - something else  */
			val = INWORD(this$port);
			CALL put$something(val, 0122H, @status);
			state = 3;
			END;

		DO;
			masterflags.busy = FALSE;
			state = 1;
			END;

		END;		/*  end case  */

Thus in PL/M you have the responsibility for coding your own RANGE
CHECKS in an example like the above.  Let state = 5 and the above
code branches off into never-never land.  Unfortunately as you maintain
a project and add new states to a machine there is no good automated
way to compute MAX_STATE for range check purposes.  I tend to put
padding cases at the end of my DO CASE structures just in "case":

		;;;;;;;;;;;	/*  insurance  */
-- 
You may redistribute this article only to those who may freely do likewise.
--
Tom Neff				UUCP:     ...!uunet!bfmny0!tneff
    "Truisms aren't everything."	Internet: tneff@bfmny0.UU.NET
Technical Details
Message-ID: <14391@bfmny0.UUCP>
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!bfmny0!tneff
References: <598@philtis.UUCP> <14381@bfmny0.UUCP> <1765@auspex.auspex.com> <14386@bfmny0.UUCP> <1782@auspex.auspex.com>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!bfmny0!tneff
From: tneff@bfmny0.UUCP (Tom Neff)
Newsgroups: comp.sys.intel
Subject: Re: PLM vs. C for 80286/80386
Keywords: PLM C
Message-ID: <14391@bfmny0.UUCP>
Date: 9 Jun 89 00:37:13 GMT
References: <598@philtis.UUCP> <14381@bfmny0.UUCP> <1765@auspex.auspex.com> <14386@bfmny0.UUCP> <1782@auspex.auspex.com>
Reply-To: tneff@bfmny0.UUCP (Tom Neff)
Organization: ^
Lines: 69