Searching \ for 'PIC vs 68K compiler (was: CCS - conversions)' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/devices.htm?key=pic
Search entire site for: 'PIC vs 68K compiler (was: CCS - conversions)'.

Truncated match.
PICList Thread
'PIC vs 68K compiler (was: CCS - conversions)'
1999\04\09@174447 by Clyde Smith-Stubbs

flavicon
face
On Fri, Apr 09, 1999 at 03:57:49PM -0500, John Payson wrote:

> the Motorola 68000.  I wonder why it's so hard for compilers to produce
> *CORRECT* code on the PIC?

Well, I can't speak for other compiler vendors, but I can tell you that
from our perspective, the single most bug-inducing feature of the PIC is
the RAM banking. Getting the bank bits right, while still keeping the code
size down, is downright tricky. This is compounded by the fact that some
chips have common RAM while some don't. The number of variations of
RAM bank configurations also contributes. About 75% of bugs we have
fixed have been RAM bank related.

There are other factors that make the PIC harder to produce bug-free code
for than say a 68K;

* the 68K is a single architecture with a flat address space,
and only minor variations in instruction sets between variants; the PIC
is 3 different architectures, with many sub-architectures, and a complex
set of address spaces.

* The 68K has large memory space available, making it easy to run large and
complex test suites; the PIC has severe resource limitations which mean test
suites have to be customized and broken up.

* The PIC architectural complexity means that the number of variations of
tests that have to be run to get the same coverage as on the 68K is
at least an order of magnitude greater, perhaps two orders of magnitude.

* The 68K has a rich set of instructions and addressing modes that make
code generation straightforward; the PIC has limited addressing modes
that make generation of some code quite convoluted. A measure of this
difference is that our PIC compiler has double the number of "productions"
in its code generator as the 68K compiler. This represents much more than
double the number of special case situations that are handled. The PIC
compiler has 6 times as much string data as the 68K compiler - which
means 6 times as many opportunities to make erorrs!

--
Clyde Smith-Stubbs               |            HI-TECH Software
Email: spam_OUTclydeTakeThisOuTspamhtsoft.com          |          Phone            Fax
WWW:   http://www.htsoft.com/    | USA: (408) 490 2885  (408) 490 2885
PGP:   finger .....clydeKILLspamspam@spam@htsoft.com   | AUS: +61 7 3355 8333 +61 7 3355 8334
---------------------------------------------------------------------------
HI-TECH C: compiling the real world.

1999\04\11@085542 by w. v. ooijen / f. hanneman

picon face
> > the Motorola 68000.  I wonder why it's so hard for compilers to produce
> > *CORRECT* code on the PIC?
>
> Well, I can't speak for other compiler vendors, but I can tell you that
> from our perspective, the single most bug-inducing feature of the PIC is
> the RAM banking. Getting the bank bits right, while still keeping the
code
> size down, is downright tricky. This is compounded by the fact that some
> chips have common RAM while some don't. The number of variations of
> RAM bank configurations also contributes. About 75% of bugs we have
> fixed have been RAM bank related.

I have almost finished re-targeting my JAL compiler from the 16x84
to the Scenix SX and I can confirm that the RAM banking is a
major nightmare. There are some minor nightmares in the code paging,
the limits of the call instruction/PC manimpulation, the missing addlw etc.
And I don't even try to generate effecient code (yet).
Is it still possible to strangle the designer of the PIC architecture or
has he/she already left for Intel?

Wouter.

1999\04\12@165607 by John Payson

flavicon
face
|Is it still possible to strangle the designer of the PIC architecture or
|has he/she already left for Intel?

When it is not necessary to switch RAM banks, the PIC's architecture is
generally quite nice.  The lack of ADDLW on the 12-bit cores is a little
annoying, but it doesn't normally cause any real problems and there isn't
exactly a lot of spare room in the opcode map (the NOP-family instructions
(e.g. sleep, tris, etc.) don't fill all possibilities, and there's no need
for 32 'clrw' variants, but beyond that there's no room for anything else.

RAM banking, of course, causes most ideas of niceness to go out the window.
Even this shouldn't be too bad, though; while some assembly programmers
might play interesting games with the banking bits, it should be pretty
easy for a compiler to know the state of the banking bits at each instruct-
ion.  The pre-code generator could thus generate code using absolute addr-
esses and an "output cleanup" stage of the compiler could generate banking
instructions.

There are only two caveats I can see with that approach:

[1] If an instruction which may be conditionally skipped needs to switch
   RAM banks, the compiler may have to 'rework' the code; e.g. on a
   16C77 [w/ shared area]

               btfss           A,0
                incf           B,f

       If A and B are both in bank 1, or one of them is in bank 1 and the other
       is in a shared area, the code would be...

               bsf             RP0
               btfss           A,0
                incf           B,f

       If A and B are in different banks, the code would become...

               bsf             RP0
               btfsc           B,0
                goto           ZZZ999
               bcf             RP0
               incf            B,f
       ZZZ999:
               ; Note: State of RP0 is unknown here!

       The 'decfsz' instruction is a bit more of a pain...

               bsf             RP0
               decfsz  A,f
                goto           ZZZ998
               goto            ZZZ999
       ZZZ998:
               bcf             RP0
               incf            B,f
       ZZZ999:
               ; Note: State of RP0 is unknown here!

[2] When a piece of the code can be reached by two routes, unless the final
   cleanup examines the code following that point, it may be unable to
   judge where to re-set the bank bits to their proper values.  For example,
   in the code examples above, if the following code was going to access
   RAM bank 1, it would be best to put a "bsf RP0" before the final label
   so it would only have to be executed if RP0 had been cleared.  In the
   "decfsz" case, if the next access will be in bank 0 it would be best to
   clear RP0 just before the "goto ZZZ999".

Still, while I can understand the PIC's banking making it harder for comp-
ilers to produce GOOD code, I still don't see why they should have trouble
producing CORRECT code [btw, the CCS compiler can even do the above types
of rewrites even on code written with inline assembly].

1999\04\13@020146 by w. v. ooijen / f. hanneman

picon face
> When it is not necessary to switch RAM banks, the PIC's architecture is
> generally quite nice.
I agree, especially for the 14 bits.

> RAM banking, of course, causes most ideas of niceness to go out the
window.
Your examples show this: the nice 2-instruction
  if ! a then b++
explodes to 5 instructions (even without code paging).

> Still, while I can understand the PIC's banking making it harder for
comp-
> ilers to produce GOOD code, I still don't see why they should have
trouble
> producing CORRECT code [btw, the CCS compiler can even do the above types
> of rewrites even on code written with inline assembly].
Producing coorect but inefficient code is not the problem.
The bugs creep in when trying to be clever....

Wouter.

1999\04\13@022933 by Tjaart van der Walt

flavicon
face
"w. v. ooijen / f. hanneman" wrote:
>
> > When it is not necessary to switch RAM banks, the PIC's architecture is
> > generally quite nice.
> I agree, especially for the 14 bits.
>
> > RAM banking, of course, causes most ideas of niceness to go out the
> window.
> Your examples show this: the nice 2-instruction
>    if ! a then b++
> explodes to 5 instructions (even without code paging).

It is interesting to see how much code space the banking
actually hogs. I've noticed a trend of about 15%-27%
depending on the program structure.

Scenix releived this problem very eloquently with their
"BANK" commands.

--
Friendly Regards          /"\
                         \ /
Tjaart van der Walt        X  ASCII RIBBON CAMPAIGN
tjaartspamKILLspamwasp.co.za  / \ AGAINST HTML MAIL
|--------------------------------------------------|
|                WASP International                |
|R&D Engineer : GSM peripheral services development|
|--------------------------------------------------|
| Mobile : .....tjaartKILLspamspam.....sms.wasp.co.za  (160 text chars) |
|     http://www.wasp.co.za/~tjaart/index.html     |
|Voice: +27-(0)11-622-8686  Fax: +27-(0)11-622-8973|
|          WGS-84 : 26¡10.52'S 28¡06.19'E          |
|--------------------------------------------------|

1999\04\13@031358 by Clyde Smith-Stubbs

flavicon
face
On Tue, Apr 13, 1999 at 07:54:24AM +0200, w. v. ooijen / f. hanneman wrote:

> Producing coorect but inefficient code is not the problem.
> The bugs creep in when trying to be clever....

And, as I indicated previously, testing is difficult because of the
number of possible combinations. It's quite easy to generate some code, and
test it successfully, but still have it fail with one particular combination
of operands in banks. This means that e.g. to fully test something like:

       a = b +c;

you have to run 4**3 (== 64) tests to properly test all combinations
of variables in 4 different banks - and that's just for one group of
devices (those with 4 RAM banks). Those with only one RAM bank, those
with two and common RAM, and those with two but no common RAM all have
to be tested as well.

Then, if the variables are 16 bit, you need to test combinations of
values that cause carry or no carry between bytes (because the propogation
of carry requires bit test and skip instructions) so you have to at least
double the number of tests. Now if they're 32 bit, you have to test for
carry propogation at least in three places. All this adds up to maybe
300 separate and distinct tests just for one statement!

Now it's true that probably not all those tests are required - if you analyze
the possibilities you can eliminate some because they don't represent materially
different cases to others - but that analysis is itself error-prone (and there's
no easy way of telling if you got the analysis right).


--
Clyde Smith-Stubbs               |            HI-TECH Software
Email: EraseMEclydespam_OUTspamTakeThisOuThtsoft.com          |          Phone            Fax
WWW:   http://www.htsoft.com/    | USA: (408) 490 2885  (408) 490 2885
PGP:   finger clydespamspam_OUThtsoft.com   | AUS: +61 7 3355 8333 +61 7 3355 8334
---------------------------------------------------------------------------
HI-TECH C: compiling the real world.

1999\04\13@101855 by Harold Hallikainen

picon face
       The use of RAM paging, as has been pointed out here, is due to the
limited instruction size and the desire to get the whole address in that
instruction so that instructions take a single word.
       It seems, however, that most RAM locations are actually used for local
dynamic (as opposed to static) variables, which could be allocated when
going into a subroutine, and released when going out of the routine.
These could be located on a (larger) stack and referenced by the stack
pointer or a base pointer.  Inside a routine, we might have an
instruction that allocates so many bytes of variables, moves the stack
and moves the stack pointer down the appropriate amount.  References to
local variables would then just be stack+1, stack+2, etc.  This would
allow very short instructions, since only a few bits would be needed to
uniquely identify the local dynamic variable on the stack.
       To release the local variables, we could just increment the stack
pointer by the appropriate amount, or the "allocate local variables"
instruction might store the number of locations used on the stack.  Then
the amount to be released could be pulled off the stack.
       This could be a larger stack that is shared with subroutine and
interrupt addresses, or could be a stack in data ram (like the 6809)
(perhaps using FSR in those machines with more than one FSR).
       It'd be interesting to maybe use bank 0 of RAM on a machine with an
extra FSR for global and static variables, then use bank 1 for dynamic
variables on a stack referenced by FSR.  We'd never have to bank switch!


Harold



___________________________________________________________________
You don't need to buy Internet access to use free Internet e-mail.
Get completely free e-mail from Juno at http://www.juno.com/getjuno.html
or call Juno at (800) 654-JUNO [654-5866]

More... (looser matching)
- Last day of these posts
- In 1999 , 2000 only
- Today
- New search...