Since there is a thread on "C friendly" architectures, I thought it
might be interested to find out what sort of horrible architectures
compiler writers actually managed to create a C compiler for.
(And what portion of the ISO C standard is/was not supported)
I asked the question (emailed Plauger if I recall correctl) once, on
why there is no "rotate" operator in C. ALL the architectures I have
ever work on had a direct assembly instruction for rotating a
register. The answer was that there were architectures which C
supports on which a "rotate" instruction made no sense. An example
was mention of an architecture that had NO integer support at the
assembly level. Integer operations had to be emulated using floating
point instructions.
Regards
Anton Erasmus
CCS and Hi-Tech have "C compilers" for the PIC12. From what I recall,
neither support reentrancy, one or t'other doesn't support the right
semantics for automatics (treats them as statics).
While I'd probably never code in a C-like language on a PIC12 through
choice, the option's there.
Not sure if there've been C compilers for any 4-bit micros -- I think
that's reaching the point where anything you write for such a small
machine is likely to be better off in assembly language. It *could* be
done, but I think humans will be better at generating code for such
CPUs.
(Can't remember who observed in the other thread that the richer the
register and instruction set of the processor, the less transparent
he expected the generated code to be, because the compiler has more
options as far as rearranging code, using different registers etc.
are concerned - but he's absolutely right - particularly on chips
with long pipelines where a lot of reordering goes on to
keep them well-fed!)
I think the ultimate challenge would be doing a compiler for the old
Motorola 14500... if you could make it drive some RAM ;)
pete
--
pe...@fenelon.com "That is enigmatic. That is textboo enigmatic..." - Dr Who
"There's no room for enigmas in built-up areas." - N Blackwell
I'm not familiar with that processor, but trying to make an optimizing
compiler for the ADSP 21xx would be a challenge -- if you ever need to
answer the question "what's a non-orthogonal instruction set" just check
that one out. Hand-optimizing assembly code would sometimes involve
backtracking 20 instructions to change register choices, then trying it
all again.
--
Tim Wescott
Wescott Design Services
http://www.wescottdesign.com
Posting from Google? See http://cfaj.freeshell.org/google/
"Applied Control Theory for Embedded Systems" came out in April.
See details at http://www.wescottdesign.com/actfes/actfes.html
But that sounds the kind of code-gen you could try with all kinds of
clever algorithms - anything up to and including the
brute-force-and-ignorance of something like GNU superopt (which seems to
have died the depth ;))
The problem with the 14500 is that it's a 1-bit controller ;) --
basically a replacement for relays ;)
pete
--
pe...@fenelon.com "That is enigmatic. That is textbook enigmatic..." - Dr Who
The arguments against using C on the PIC12 include lack of
portability and lack of re-entrant code. (At least one compiler
has implemented re-entrant code on a PIC 12 more as a check
box issue rather than a practical use)
We have found that code is quite portable to processors
designed for a similar applications and less so for other processors.
Very few very small embedded systems require re-entrancy
in their applications and my experience is that it more of a C
language requirement than an application implementation requirement.
Rotates, adds and subtracts with carry are all instructions that
support extended precision integer operations. It is interesting
that the extensions in ISO C standards for embedded systems
TR18037 makes it easy to create compilers that can support
these instructions without resorting to assembly code.
There have been worse processors than the Microchip PIC12
proposed for use in embedded systems. The PIC 12 found its
niche when it started being used in very small single purpose
applications and then the HLL started to make sense for it.
When we implemented a C compiler for the PIC12 tracking
the paging and instruction side effects were the most time
consuming.
w..
The AVR tiny micros must be pretty close (the real, ramless tinies).
The ISA itself is not too bad (except for the separate code and data
spaces), but on the tiny's there is no RAM - only the 32 registers.
There is a three-level hardware return stack, but no sensible way to
make a data stack (although since the registers are memory-mapped to the
data space, the single pointer register could theoretically be used as a
data stack pointer). There's a C compiler from ImageCraft, and it's
also possible to get gcc to work with it (although it involves a little
bit of trickery).
HP-1000 mini computers, (16 bit.) I am sure they are not the worst
possible architecture for implementing C, but they had their quirks.
(They were basically a 16 bit version of DEC's 12 bit PDP-8)
A long time ago I ported the Small-C compiler to an HP-2113 and had to
overcome the following:
(a) Register set: Two accumulators, two index registers. (an
architectural improvement over the original, that had only the two
Accs)
The X & Y index registers provided a few more operations and
addressing modes at the cost of one or two more words, and one or two
more memory access cycles. After trying a few alternate designs I
found out that, in most cases, I could produce smaller and faster code
if I did not use the index registers at all.
(b) No hardware stack support - Must simulate stacks in software to
support recursion or in-stack local variables, etc.
(c) Limited addressing range inside the 32Kword address space. Opcodes
could directly address operands in the same "page" were the opcode was
located, or in page-0. I believe a page was a block of memory 1024
words. It was not a relative address, which would have been a little
more usable. Anything else could only be accessed using indirect
addressing via a pointer in memory. Setting the MSB in a word address
added (in hardware) an extra level of indirection. i.e, trying to
fetch the word pointed by 0x8123 will fetch the word whose address was
stored at address 0x0123. If that word also had the MSB set one more
level of indirection will ensue, and so on.
(d) Different addresses for 16-bit words and 8-bit bytes at the same
memory location. There were a few byte and string oriented
instructions using the index registers mentioned above, but they used
a different addressing form. The basic architecture used word
addressing. From 0x0000 to 0x7fff words. (32Kwords, 64Kbytes)
The byte instructions used 0x0000 to 0xffff. The word at address N
contained the bytes at (byte) addresses 2N and 2N+1.
Again, after a few false starts trying to save memory, I just made
char = int = 16 bit.
I got the compiler to work, but after a while I abandoned it and
returned to Ratfor, which offered the same or more functionality than
the original Small-C. (sans recursion)
Those are more or less obsolete by now...
Hasn't been any new RAMless tiny's introduced in years
> The ISA itself is not too bad (except for the separate code and data
> spaces), but on the tiny's there is no RAM - only the 32 registers.
> There is a three-level hardware return stack, but no sensible way to
> make a data stack (although since the registers are memory-mapped to
> the data space, the single pointer register could theoretically be
> used as a data stack pointer). There's a C compiler from ImageCraft,
> and it's also possible to get gcc to work with it (although it
> involves a little bit of trickery).
--
Best Regards,
Ulf Samuelsson
u...@a-t-m-e-l.com
This message is intended to be my own personal view and it
may or may not be shared by my employer Atmel Nordic AB
There was an early C compiler for the GE 635, which had (36-bit) word
addressing. Characters (6-bit) and bytes (9-bit) could be addressed only
via extra indirection words. Where an ordinary pointer fit in 18 bits and
could be in a register, byte or character pointers needed 36 and could
only be in memory.
On the other hand, it was otherwise pretty conventional - flat address
space (unless you were running Multics on a VM-enabled processor),
call/return through registers or memory stacks, twos complement.
--
mac the naïf
Has anyone actually used the 14500 ? - an example of a real application
would be interesting.
-jg
> Rotates, adds and subtracts with carry are all instructions that
> support extended precision integer operations. It is interesting
> that the extensions in ISO C standards for embedded systems
> TR18037 makes it easy to create compilers that can support
> these instructions without resorting to assembly code.
Can you clarify this - do you mean you will be (finally)
able to (eg) RotateRight(arg), and RotateRightCY(arg) ?
-jg
The real application is for a PLC-like controller. Think ladder logic.
Best regards,
Spehro Pefhany
--
"it's the network..." "The Journey is the reward"
sp...@interlog.com Info for manufacturers: http://www.trexon.com
Embedded software/hardware/analog Info for designers: http://www.speff.com
> On Thu, 08 Jun 2006 10:39:02 +1200, the renowned Jim Granville
> <no....@designtools.co.nz> wrote:
<snip>>>
>>>The problem with the 14500 is that it's a 1-bit controller ;) --
>>>basically a replacement for relays ;)
>>
>>Has anyone actually used the 14500 ? - an example of a real application
>>would be interesting.
>>
>>-jg
>
>
> The real application is for a PLC-like controller. Think ladder logic.
I realise what Motorola intended it to be used for; I'm curious if
anyone actually did a design using one ?
I have seen PLCs using the Signetics 8X300, which relative to the
14500, was an advanced chip :)
-jg
>
> Has anyone actually used the 14500 ? - an example of a real application
> would be interesting.
A customer had a 14500-based PLC board for a packing machine back in
1981-ish when PLCs were expensive. Hex keypad program entry, EEPROM
program memory. I used to write programs for it, using a photocopied
coding sheet. It was an antique way of doing things even then. I've
still got one of them around somewhere.
Paul Burke
Wow, thanks.
Was that x8 EPROM, or wider ?
Did you ever code counters in this ?
I've been mulling over the idea of doing a 14500 in a CPLD,
mainly as a teaching exercise.
I can see simple ladder logic is do-able, but then wondered how to
implement something like a counter, as the opcodes seem just a little
short on that. No atomic complement data, for example,
SKZ, but not SKNZ, and I'd be tempted to allow longer Skip sizes.....
Maybe it needs a 14500++ :)
-jg
> Wow, thanks.
> Was that x8 EPROM, or wider ?
> Did you ever code counters in this ?
>
I've just dug it out of the glory hole... the one I've got here is a
very late one, with 85 date codes on the chips. The program store is an
XC2816 with an RS label (that was shortly after they'd stopped being
Radiospares). The RAM is a 2147. Sadly I junked all the circuit diagrams
etc. about 6 years ago.
I never did counters, it was all straightforward relay replacement stuff.
Paul Burke
TR 18037 allows direct access to the processors registers. If the
condition codes are declared as a
register volatile struct {
int is_IRQ
: 1;
int disable_FIRQ : 1;
int half_carry
: 1;
int disable_IRQ : 1;
int N
: 1;
int Z
: 1;
int V
: 1;
int C
: 1;
} CC;
then
c = a + CC.C + b;
should now generate a
load a
adc b
store c
sequence. Similarily other instructions that
involve condition code access can now be used.
w..
Please don't use html and/or attachments in usenet.
--
"Our enemies are innovative and resourceful, and so are we.
They never stop thinking about new ways to harm our country
and our people, and neither do we." -- G. W. Bush.
"The people can always be brought to the bidding of the
leaders. All you have to do is tell them they are being
attacked and denounce the pacifists for lack of patriotism
and exposing the country to danger. It works the same way
in any country." --Hermann Goering.
-jg
> Jim Granville wrote:
>
>> Wow, thanks.
>> Was that x8 EPROM, or wider ?
>> Did you ever code counters in this ?
>>
>
> I've just dug it out of the glory hole... the one I've got here is a
> very late one, with 85 date codes on the chips. The program store is an
> XC2816 with an RS label (that was shortly after they'd stopped being
> Radiospares). The RAM is a 2147. Sadly I junked all the circuit diagrams
> etc. about 6 years ago.
You probably thought no one would ever ask about it :)
> I never did counters, it was all straightforward relay replacement stuff.
Thanks.
I've worked out that counters are possible, with some small extensions.
As time allows, I think I'll code a 14500, then re-map the 16 opcodes to
remove dead spaces...
-jg
Would this work if compiler is smart enough?
#define RRC(c) CC.C?(c >> 1)|0x80:(c >> 1)
#define RR(c) { unsigned short tmp;
tmp = c & 0x80;
c = (c >> 1) | tmp;
}
#define RLC CC.C?(c << 1)|0x01:(c << 1)
#define RL(c) c = (c << 1) ; c |= CC.C;
I/O accesses seems to be converted to ints before use, this sucks...
iowr(PORT,iord(PORT) | (1 << bit));
to set a bit :-(
PORT.bit = 1;
Would be nicer...
Even rather stupid compilers like sdcc will create rotate instructions
for code like this:
c = (c << 1) | (c >> 7);
c = (c << 7) | (c >> 1);
Philipp
Certainly would, it would bring C code to where Modula-2 has been for
over 15 years :)
I think Walter's example should also expand for Ports, as he creates a
struct of bits
( tho each element is int :1, not bit, which I thought was now C-legal ? )
ie if one can accsss Carry as CC.C, then any port should be accessible
as PortName.BitName ?
-jg
There was a lot of effort in when TR18037 was written to include those
things that collectively we has some experience with.
Access to the registers and user defined memory have seen a lot of use.
w..
Many do, but is it "Embedded C"?
> There was a lot of effort in when TR18037 was written to include those
> things that collectively we has some experience with.
>
> Access to the registers and user defined memory have seen a lot of
> use.
>
But can you define which register you are using?
The IAR construct:
__no_init __regvar unsigned char my_register_variable @ 2;
tells you to use register 2.
This is very useful for small applications, allowing global variables in
regusters.
Ulf Samuelsson wrote:
> Walter Banks wrote:
> > Our C compilers can access PortName.BitName. In the more general case
> > ports can more than one bit field be typed or mapped on structs.
> >
>
> Many do, but is it "Embedded C"?
The Embedded TR18037 formally defined this wide spread practice.
> But can you define which register you are using?
Global variables can be allocated to specific registers or allocated to the next available register. The compiler sees this as an application constraint and creates code using the remaining registers for locals and temporaries.
> This is very useful for small applications, allowing global variables in
> regusters.
Agreed.
w..
I thought someone else would mention it by now, but another notorious
example is the word-addressed DG Nova, which required a separate
pointer format to address bytes. C compilers existed for this
architecture; Chris Torek and Michael Meissner often mention its
quirks:
http://groups.google.com/group/alt.folklore.computers/msg/b7a12c8764051e8e
http://groups.google.com/groups?as_q=nova+pointer&as_uauthors=chris+torek
>Alex Colvin wrote:
>> >Since there is a thread on "C friendly" architectures, I thought it
>> >might be interested to find out what sort of horrible architectures
>> >compiler writers actually managed to create a C compiler for.
>>
>> There was an early C compiler for the GE 635, which had (36-bit) word
>> addressing. Characters (6-bit) and bytes (9-bit) could be addressed only
>> via extra indirection words. Where an ordinary pointer fit in 18 bits and
>> could be in a register, byte or character pointers needed 36 and could
>> only be in memory.
The same problems occurred with the Univac-11xx series, which used
word addressing with 36 bit words and 6/9 bit characters.
>I thought someone else would mention it by now, but another notorious
>example is the word-addressed DG Nova, which required a separate
>pointer format to address bytes.
This problem also occurs with any 16/24/32 bit DSP, which do not have
byte addressing.
In many Pascal systems, this problem was solved with the "packed array
of char", which had a limited set of operands compared to "array of
char", in which each character occupied a memory word.
In future high level systems with 64 bit ALUs, do we really need 8 bit
byte addressing ? The 8 bit byte is insufficient to express all
characters in many major languages of the world.
The Unicode scalar value (USV) range is 0.. 0x10FFFF, thus requiring
21 bits, thus, three Unicode characters would nicely fit into a 64 bit
word with one spare bit ("UTF-64"). Some kind of packed array of char
mechanism would be required to access individual characters.
Paul
Now I'm really getting déjà vu.
>
> Paul
I had to program that thing in Interpreted BASIC.... It ran the whole
company!
>
--
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills Staffs England /\/\/\/\/
/\/\/ ch...@phaedsys.org www.phaedsys.org \/\/\
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
Someone who programmed the Singer minis once told me about their
architecture. They had to be programmed in assembler and the assembly
language was so convoluted that they had to use a pre-processor written
in Snobol.
Leon
The Novas were a great step forward from the previous one, the Digital
PDP-8. The history of Novas is tied tightly with PDP-8 and PDP-11.
The Nova is what was initially thought to become a PDP-11, but the
designers spun off Digital and set up an own company.
IIRC, the Novas are older than the C language, which was initially
set up on a PDP-11.
The idea of addressing everything as bytes was new in the minicomputer
world with the PDP-11, although on the mainframe side it was already
used in the IBM S/360.
--
Tauno Voipio
tauno voipio (at) iki fi
"[..]
If you design with a PIC you will prefer a C Compiler, CCS does a good
one [..]"
Though ANSI/ISO C compliance is not something one expects in a
microcontroller, I had portable ISO C code compiled with various compilers
on various desktops and workstations. Trying to get CCS's C compiler to
work with it was a struggle I never succeeded in, though it was possible
after fewer modifications than with CCS to compile it with SDCC for the
8051 (though I admit in that case, SDCC's resultant object code was too
large for 64KB).